Javascript-форум (https://javascript.ru/forum/)
-   Angular.js (https://javascript.ru/forum/angular/)
-   -   ng-repeat кастомный фильтр для фильтрации обьектов (непонятное поведение) (https://javascript.ru/forum/angular/40264-ng-repeat-kastomnyjj-filtr-dlya-filtracii-obektov-neponyatnoe-povedenie.html)

VerDiz 30.07.2013 01:51

ng-repeat кастомный фильтр для фильтрации обьектов (непонятное поведение)
 
Доброго времени суток!

В руководстве написанно, что ng-repeat работает только с массивами.
Часто возникает нужда в хешах и нужно их обходить с помощью ng-repeat и применить filter. Ниже приведенный пример работает, но не так как надо - игнорирует фильтр.

<div ng-app="tmp">
    <div ng-controller="Ctrl">
        <ul ng-repeat="(key,value) in items | filter:{val:1}"> {{value.name}}         </ul>
    </div>
<div>


angular.module('tmp',[])
.controller('Ctrl',['$scope', function(data) {
    data.items = {
     a:{name:'a1', val:1},
     b:{name:'a2', val:2},
     c:{name:'a3', val:1}
    }
}])


Выход есть - это создать свой фильтр. Ниже приведенный пример(Фильтр) работает так, как надо.

.filter('customFilter',function(){
    return function (items, criterion) {
        console.log('Джина вызывали?')
        var tmp = {};
        for(var i in items){
            var item = items[i];
            if(item.val == criterion.val){
                tmp[i] = item;
            }
        }
        return tmp;
    }
})


Теперь собственно вопрос:
Почему сообщение "Джина вызывали?" в консоль выводится два раза?

Вот фидл с примером http://jsfiddle.net/yMLt9/

Shitbox2 30.07.2013 08:46

Тут есть пример http://plnkr.co/edit/lRkvtMyIuscsvIIZn8CA?p=preview

VerDiz 30.07.2013 09:03

Цитата:

Сообщение от Shitbox2 (Сообщение 265017)

Я конечно извиняюсь, но я в вопросе и так показал, как филтр работает.
Меня интересую всовсем другой вопрос (о поведении кастомного фильтра и наверное не только кастомного) и я его задал в конце своего поста.

Почему сообщение "Джина вызывали?" в консоль выводится два раза?
Вот фидл с примером http://jsfiddle.net/yMLt9/

xAockd 30.07.2013 12:07

Тоже интересен ответ, но такая история и с $scope.$watch

Shitbox2 31.07.2013 12:02

C $scope.$watch другая история. Просто у него могут быть срабатывания, когда старое и новое значение равны.

Здесь же надпись «Джина вызывали» появляется второй раз только если появился элемент, попадающий в выборку. Скорее всего, это сделано для того, чтобы к новому элементу применить следующие фильтры по цепочке.

nerv_ 31.07.2013 15:12

Цитата:

Сообщение от VerDiz
Почему сообщение "Джина вызывали?" в консоль выводится два раза?

предлагаю задать этот вопрос разработчикам ангуляра и сообщить нам о результатах расследования :)

Riim 01.08.2013 05:46

выполняется scan пока есть изменения (если больше 9 срабатываний: Uncaught Error: 10 $digest() iterations reached. Aborting!). При первом они есть, при втором их нет. Вот так есть при втором, третий scan срабатывает в холостую:
angular.module('tmp',[])
.controller('Ctrl',['$scope', function(data) {
    data.items = {
     a:{name:'a1', val:1},
     b:{name:'a2', val:0},
     c:{name:'a3', val:0}
    }
}]).filter('customFilter',function(){
    return function (items, criterion) {
        console.log('Джина вызывали?')
        var tmp = {};
        for(var i in items){
            var item = items[i];
            if(item.val == criterion.val){
                tmp[i] = item;
            }
            item.val++;
        }
        
        return tmp;
    }
})


а так при третьем, четвертый - холостой:

angular.module('tmp',[])
.controller('Ctrl',['$scope', function(data) {
    data.items = {
     a:{name:'a1', val:1},
     b:{name:'a2', val:0},
     c:{name:'a3', val:-1}
    }
}]).filter('customFilter',function(){
    return function (items, criterion) {
        console.log('Джина вызывали?')
        var tmp = {};
        for(var i in items){
            var item = items[i];
            if(item.val == criterion.val){
                tmp[i] = item;
            }
            item.val++;
        }
        
        return tmp;
    }
})

nerv_ 01.08.2013 17:26

Riim, и какое отношение это имеет к вопросу? ) (лишнее срабатывание)

Riim 02.08.2013 05:50

Цитата:

Сообщение от nerv_
и какое отношение это имеет к вопросу? ) (лишнее срабатывание)

я вроде как раз и объяснил почему оно происходит. Если что не понятно, спрашивай.

nerv_ 03.08.2013 23:40

Цитата:

Сообщение от Riim
я вроде как раз и объяснил почему оно происходит. Если что не понятно, спрашивай.

т.е. аргумент на холостое срабатывание выглядит как
Цитата:

Сообщение от Riim
выполняется scan пока есть изменения

?


Часовой пояс GMT +3, время: 20:30.