Search code examples
javascriptangularjsangularjs-digest

Angular elements bound to same function. Avoid multiple call on each digest


Given the following:

<div data-ng-repeat="val in vals">
      <div data-ng-class:{'myClass':isEngineOn(val)}>
          <span data-ng-show="isEngineOn(val)">yeah it's on</span>
          <span data-ng-show="!isEngineOn(val)"> standby</span>
          <button data-ng-disabled="isEngineOn(val)">Start engine</button>
      <div>
</div>

isEngineOn changes with websocket messages I receive from the server.

Is there a way to avoid evaluating isEngineOn, 4 times during each digest, per each value in the repeat? Something like initializing a variable or something?


Solution

  • Yes, just have a variable in the controller that holds the result, and update that variable when you receive an update from the server:

    In your controller:

    $scope.engineOn = isEngineOn();//also make sure to update from server whenever you need
    

    Note that if your isEngineOn() function is no longer called from the view it doesn't need to be on the scope, it can be declared as a regular variable.

    HTML:

    <div data-ng-class="{'myClass':engineOn}">
          <span data-ng-show="engineOn">yeah it's on</span>
          <span data-ng-show="!engineOn"> standby</span>
    <div>
    

    EDIT 2: The ng-init, as you said, did not update on digest so I've taken a second approach.

    I've taken the long way round, and created a corresponding array for your values and you can read from that:

      <div data-ng-repeat="val in vals" >
          <div data-ng-class="{'myClass':enginOn[val]}">
              <span data-ng-show="engineOn[val]">yeah it's on</span>
              <span data-ng-show="!engineOn[val]"> standby</span>
              <button data-ng-disabled="isEngineOn(val)">Start engine</button>
          </div>
    </div>
    

    Fiddle.