mdim
mdim

Reputation: 115

Abstracting ng-class statement

I'm trying to place relatively complex logic with nested variables within an ng-class variable in my UI.

Currently, it looks something like

ng-class="
    {
        'active': MyView.is_sorter($index),
        'smallblock90':(MyView.navFlow.selectedPanel == 'players' 
                        && MyView.stat_type == 'box'),
        'smallblock80':(MyView.navFlow.selectedPanel != 'players' 
                        && MyView.stat_type == 'shoot')
    }"

Now, this (or very slightly different) logic occurs frequently throughout my code and is obviously very cumbersome to be in the UI. Is there any way to abstract this, or a better approach that should be taken?

To give some perspective, I'm trying to adjust the width of div's based on some panels being selected. The divs are normally at 70px, but under certain conditions may change to 80px or 90px

Upvotes: 0

Views: 54

Answers (2)

Joao Polo
Joao Polo

Reputation: 2163

You can to return an array of classes from a function to ng-class. Look this sample: http://jsbin.com/jewili/edit?html,css,js,output

<div ng-class="myTest(1)">passing one</div>

and the function myTest:

$scope.myTest = function(arg) {
    var out = [];
    if(arg == 1 || arg == 2)
        out.push('classA');
    if(arg == 2) {
        out.push('classB');
    }
    if(arg == 3) {
        out.push('classC');
    }
    return out;
};

you can test anything in the function, not only arguments... You can test MyView.navFlow.selectedPanel or others vars

Upvotes: 1

Mikko Viitala
Mikko Viitala

Reputation: 8404

You could wrap your logic inside a directive (complete sample).

<body ng-app="app" ng-controller="Ctrl">
  <fieldset>
    <p blocks="myView">Some content here</p>
  </fieldset>
</body>

angular.module('app',[])
  .controller('Ctrl', function($scope) {
    $scope.myView = {
      active: true
    };
  })

  .directive('blocks', function($compile) {
    return {
      restrict: 'A',
      scope: {
        blocks: '='
      },
      link: function(scope, element) { 
        element.removeAttr('blocks');
        element.attr('ng-class', '{ \'active\': blocks.active }');
        $compile(element)(scope);
      }
    };  
  });     

.active {
  color: #ff0000; 
}

enter image description here

And as a side note you really should always do comparisons using ===/!== and follow naming convention, so is_sorter would become isSorted.

Upvotes: 1

Related Questions