Угловые элементы привязаны к одной и той же функции. Избегайте многократных звонков в каждом дайджесте

Учитывая следующее:

<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 изменяется с сообщениями websocket, которые я получаю от сервера.

Есть ли способ избежать оценки isEngineOn, 4 раза во время каждого дайджеста, для каждого значения в повторе? Что-то вроде инициализации переменной или что-то?

3 ответа

Решение

Да, просто укажите в контроллере переменную, которая содержит результат, и обновите эту переменную при получении обновления с сервера:

В вашем контроллере:

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

Обратите внимание, что если ваш isEngineOn() функция больше не вызывается из представления, она не должна находиться в области видимости, она может быть объявлена ​​как обычная переменная.

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>

РЕДАКТИРОВАТЬ 2: ng-initКак вы сказали, не обновлялся в дайджесте, поэтому я выбрал второй подход.

Я прошел длинный путь и создал соответствующий массив для ваших значений, и вы можете прочитать из этого:

  <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>

Скрипка

Вы можете сделать это с помощью простого CSS и без вызова функции в пролетах. Я думаю, что это гораздо эффективнее, чем решение на JavaScript, особенно если у вас есть повторение для многих элементов, потому что вы можете сохранить привязки:

<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;
}

JS Fiddle

Вы можете установить наблюдателя на переменную, которая изменяется при получении ответа от сервера, например:

scope.$watch(function(){ return <var that changes>; }, function(oldv, newv){
    if(oldv !== newv)
        scope.isEngineOn = <Calculate here>;
});

Тогда используйте:

<span data-ng-show="isEngineOn">
Другие вопросы по тегам