Reputation: 1405
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?
Upvotes: 0
Views: 370
Reputation: 984
You can do that with simple CSS and without calling the function in the spans. I think thats much more efficient than a JavaScript solution, especially when you have a repeat over many elements because you can save bindings:
<div data-ng-repeat="val in vals">
<div data-ng-class:{'myClass':isEngineOn(val)}>
<span class="showWhenOn">yeah it's on</span>
<span class="showWhenOff"> standby</span>
<button onclick="alert('Starting...')">Start engine</button>
</div>
</div>
CSS:
.showWhenOn {
display: none;
}
.myClass .showWhenOn {
display: inline;
}
.myClass .showWhenOff {
display: none;
}
.myClass button {
pointer-events: none;
color: silver;
}
Upvotes: 1
Reputation: 17064
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>
Upvotes: 0
Reputation: 26940
You can set watcher to variable that changes when you receive answer from server, for example:
scope.$watch(function(){ return <var that changes>; }, function(oldv, newv){
if(oldv !== newv)
scope.isEngineOn = <Calculate here>;
});
Then use:
<span data-ng-show="isEngineOn">
Upvotes: 0