Steve Crane
Steve Crane

Reputation: 4440

Can AngularJS ngClass expressions be nested?

I'm new to AngularJS and have been assigned a maintenance task on an app we've inherited (originally developed for us by a third-party).

At the left of a header row in a table is a small button showing either a plus (+) or minus (-) symbol to indicate whether it will expand or collapse the section when clicked. It does this using ngClass as follows.

ng-class="{false:'icon-plus',true:'icon-minus'}[day.expanded]"

I have to remove the button when there is no data in the section and thus no ability to expand. There is already a class (.plus-placeholder) for this and I was wondering if the expressions that ngClass uses can be nested to allow something like this

ng-class="{false:'plus-placeholder',true:{false:'icon-plus',true:'icon-minus'}[day.expanded]}[day.hasTrips]"

which would allow me to add a hasTrips property to day to accomplish the task.

If this is not possible I think I will need to add a property something like expandoState that returns strings 'collapsed', 'expanded' and 'empty'. so I can code the ngClass like this

ng-class="{'collapsed':'icon-plus','expanded':'icon-minus','empty':'plus-placeholder'}[day.expandoState]" 

And perhaps this is a cleaner way to do it in any case. Any thoughts/suggestions? Should it be relevant, the app is using AngularJS v1.0.2.

Upvotes: 0

Views: 1391

Answers (1)

Andyrooger
Andyrooger

Reputation: 6746

You certainly can do either of the two options you have mentioned. The second is far preferable to the first in terms of readable code.

The expandoState property you mention should probably be a property or a method placed on the scope. Your attribute would then read something like

ng-class="{'collapsed':'icon-plus','expanded':'icon-minus','empty':'plus-placeholder'}[expandoState()]"

To put this method on the scope you would need to find the relevant controller. This will probably be wherever day is assigned to the scope. Just add

$scope.expandoState = function() {
    // Return current state name, based on $scope.day
};

Alternatively, you could write a method on the controller like

$scope.buttonClass = function() {
    // Return button class name, based on $scope.day
};

that just returns the class to use. This will let you write the logic from your first option in a much more readable fashion. Then you can use

ng-class="buttonClass()"

Upvotes: 1

Related Questions