Функция контроля вызова ng-repeat слишком много раз

У меня есть следующий код (события это массив):

<tr ng-repeat="event in events">
    <td>
        <span time-ago="{{event.TimestampSec}}"></span>
    </td>
    <td>
        {{prepareAlertValue(event.AlertValue)}}
    </td>
</tr>

давным-давно - моя таможенная директива. Выполняется events.length раз.

Мой контроллер:

...
window.callPrepareAlertValueCount = 0

$scope.prepareAlertValue = function(value) {
    window.callPrepareAlertValueCount++;
    if(safemineHelper.isFloat(value)) {
        value = (~~(value * 100)) / 100;
    }
    return value;
}
...

После того, как список показан - я вижу, что callPrepareAlertValueCount растет. Консольный журнал:

 > callPrepareAlertValueCount
 < 41890
 > callPrepareAlertValueCount
 < 46150
 > callPrepareAlertValueCount
 < 480315

Пожалуйста, может кто-нибудь объяснить, почему prepareAlertValue выполняется все время. Нужно ли писать директивы для каждой функции форматирования?

4 ответа

Решение

Это правильно, что бы вы ни связывали с html, он вызывается при каждом цикле дайджеста, выполняемого угловым js.

использование {{::prepareAlertValue(event.AlertValue)}} директива bind Once, которая будет выполнять эту функцию только один раз.

Примечание Bind Once работает только для выше Angular 1.3+

Angular не знает, что происходит внутри prepareAlertValue(), поэтому он должен вызывать эту функцию при каждом дайджесте.

callPrepareAlertValueCount является глобальной переменной в окне и обновляется всякий раз, когда prepareAlertValue функция называется.

Уловка в том, что он вызывается всякий раз, когда происходит цикл дайджеста. Всякий раз, когда вносится изменение, такое как событие щелчка, запускается (через Angular с ng-click) или ваш events массив изменяется, что запускает цикл $digest. Когда запускается $digest, функция переоценивается, так как все угловые наблюдатели переоцениваются, и увеличивается callPrepareAlertValueCount, Так бывает гораздо больше, чем events.length,

По сути, вы не должны полагаться на счетчик, поскольку у вас нет контроля над тем, сколько раз выполняется циклы $digest.

Вот простая скрипка, которая демонстрирует это.

Вы можете перестать вызывать функции контроллера внутри ng-repeat. или если вы хотите вызвать функцию контроллера внутри цикла (ng-repeat), то используйте надлежащие условия (в вашем контроллере), если true, тогда вызовите функцию, если вы этого не сделаете, тогда она будет вызывать функцию контроллера каждый раз,

Другие вопросы по тегам