Angular.js передать фильтр для директивы двунаправленного ('=') атрибута
Мне нужно использовать директиву sublist
в нескольких местах страницы, и она должна содержать иногда полный список fields
, но иногда фильтруется. Вот мой наивный подход:
HTML:
<div ng-controller="MainCtrl">
<sublist fields="fields" /> <!-- This one is OK -->
<sublist fields="fields | filter: 'Rumba'" /> <!-- This one raises error -->
</div>
JavaScript:
angular.module('myApp', [])
.directive('sublist', function () {
return {
restrict: 'E',
scope: { fields: '=' },
template: '<div ng-repeat="f in fields">{{f}}</div>'
};
})
.controller('MainCtrl', function($scope) {
$scope.fields = ['Samba', 'Rumba', 'Cha cha cha'];
});
http://jsfiddle.net/GDfxd/14/
Когда я пытаюсь использовать фильтр, я получаю эту ошибку:
Error: 10 $digest() iterations reached. Aborting!
Есть ли решение этой проблемы?
Ответы
Ответ 1
Ошибка итераций $digest обычно возникает, когда наблюдатель изменяет модель. В случае ошибки привязка fields
привязана к результату фильтра. Это привязка создает наблюдателя. Поскольку фильтр возвращает новый объект из вызова функции каждый раз, когда он запускается, он вызывает постоянный запуск наблюдателя, потому что старое значение никогда не совпадает с новым (см. этот комментарий от Игоря в Google Группы).
Хорошим решением было бы привязать fields
в обоих случаях, например:
<sublist fields="fields" /></sublist>
И добавьте еще один необязательный атрибут ко второму случаю для фильтрации:
<sublist fields="fields" filter-by="'Rumba'" /></sublist>
Затем настройте свою директиву так:
return {
restrict: 'E',
scope: {
fields: '=',
filterBy: '='
},
template: '<div ng-repeat="f in fields | filter:filterBy">'+
'<small>here i am:</small> {{f}}</div>'
};
Примечание. Не забудьте закрыть теги sublist
в своей скрипте.
Вот скрипка
Ответ 2
Исправленная скрипта
Проверьте связанный пост здесь.
В скрипке вам нужно будет закрыть теги.
Хотя у вас все еще могут быть теги с автономным содержимым, которые у вас есть.
<sublist fields="fields" filter="'Rumba'"/> <!-- Tested in chrome -->