简体   繁体   中英

angularjs custom filter for search in an Array of objects

I have an Object

{"A":[],"B":[],"C":[],"D":[],"E":[],"F":[{"name":"Fargo","id":29}],"G":[],"H":[],"I":[],"J":[],"K":[],"L":[],"M":[],"N":[],"O":[],"P":[],"Q":[],"R":[],"S":[{"name":"Sullivan","id":23},{"name":"Sven","id":26}],"T":[],"U":[],"V":[],"W":[],"X":[],"Y":[],"Z":[],"#":[]}

I need to write an angular js filter based on the object name . I'm would like to display a result every time that the user enters a new character.

For that purpose I've created this filter :

app.filter('alphabeticSearch', function () {
    return function (obj,query) {
                if (!query) {
        return obj;
    }
    var filtered = {};
    for (var i = 65; i < 91; i++) {
        filtered[String.fromCharCode(i)] = [];
    }
    filtered['#'] = [];
    for (i in obj) {
        var _this = obj[i];
        filtered[i] = _this.filter(function (ele) {
            var reg = new RegExp(query, "gi");
            return reg.test(ele.name);
        })
    }
    return filtered;
    };
});

But the angularjs throws an error

[$rootScope:infdig] 10 $digest() iterations reached. Aborting!

This is how I'm using the filter from my HTML

<input type='text' id='cSearch' ng-model='ent' value='' />
<div ng-repeat="(letter,obj) in item | alphabeticSearch:ent">
   ....
</div>

That's because your filter is retrieving a new instance for the same obj and query every time.

Angular will evaluate the expression of your filter in each diggest in order to find changes, so in each diggest angular is checking what's the result of your filter, and unless something has changed with one of the parameters of the filter angular expects the result to be the same. You would think that the code of your filter is retrieving the exact same thing every time, but it's not, because your function is creating a new instance every time, and that makes angular think that things are not the same, so it tries to re-evaluate again in order to get a consistent response from your filter function, but your function is retrieving a new object again, so angular tries again... and when this has happened 10 times angular aborts the process throwing an exception.

Changing a few things in your filter should solve the issue:

app.filter('alphabeticSearch', function () {
    var filtered = {};
    var lastObj={};
    var lastQuery="";
    return function (obj,query) {
       if (!query) 
           return obj;
        if(angular.equals(obj, lastObj) && angular.equals(query,lastQuery))
            return filtered;

        lastObj = angular.copy(obj);
        lastQuery = angular.copy(query);
        filtered={};
        for (var i = 65; i < 91; i++) {
            filtered[String.fromCharCode(i)] = [];
        }
        filtered['#'] = [];
        for (i in obj) {
            var _this = obj[i];
            filtered[i] = _this.filter(function (ele) {
                var reg = new RegExp(query, "gi");
                return reg.test(ele.name);
            })
        }
        return filtered;
    };
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM