angularjs自定义过滤器,用于在对象数组中进行搜索

时间:2014-09-24 12:13:11

标签: javascript angularjs angularjs-ng-repeat angularjs-filter

我有一个对象

{"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":[],"#":[]}

我需要根据对象angular js filter编写name。我想在每次用户输入新角色时显示结果。

为此,我创建了这个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;
    };
});

但是angularjs会抛出错误

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

我正在使用HTML中的过滤器

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

1 个答案:

答案 0 :(得分:2)

这是因为您的过滤器每次都会检索相同objquery的新实例。

Angular会在每个diggest中评估过滤器的表达式,以便找到更改,因此在每个diggest角度检查过滤器的结果是什么,除非某些内容已经更改了滤波器角度的参数要求结果相同。您会认为过滤器的代码每次都检索完全相同的东西,但事实并非如此,因为您的函数每次都在创建一个新实例,这使得角度认为事情不一样,所以它试图重新 - 再次评估,以便从过滤器函数中获得一致的响应,但是您的函数再次检索一个新对象,因此角度再次尝试...当发生这种情况时,10次角度中止该过程抛出异常。

更改过滤器中的一些内容可以解决问题:

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;
    };
});