Функция контроля вызова 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, тогда вызовите функцию, если вы этого не сделаете, тогда она будет вызывать функцию контроллера каждый раз,