Search code examples
angularjsng-class

How to bind both once and not once using ng-class


How can I sucessfully do this?

ng-class="{'a':x, 'b':::y}"

Notice how I'm trying to bind only once with "y" but not with "x"

I also tried using multiple ng-class directives, like this:

<div ng-class="{'a':x}" ng-class="::{'b':y}"></div>

but doesn't work either.


Solution

  • The problem is that you can only specify one-time binding syntax :: at the beginning of the expression. Here your expression is an object literal and using :: before the second key value results in an invalid syntax. You would have to split them up and probably place one section in the class expression (There is no point using 2 ng-class directives).

    Example:

    ng-class="{'a':x}" class="someclass {{::{true:'b'}[y]}}"
    

    Documentation

    An expression that starts with :: is considered a one-time expression. ....

    .a {
      color: green;
    }
    .b {
      color: blue;
    }
    .a.b {
      color: red;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
    <div ng-app>
    
      <div ng-class="{'a':x}" class="{{::{true:'b'}[y]}}">Test</div>
      X->
      <input type="checkbox" ng-model="x">Y->
      <input type="checkbox" ng-model="y">
    
    </div>

    Note: One time binding will keep the watch until it gets an non undefined value for the bound property. If the property value is available at the time view renders (i.e not asyncronous) you could just do

    <div ng-class="{'a':x}" class="{{::y ? 'b': ''}}">Test</div>
    

    as well.