angularjs 具有分离器功能的过滤器

angularjs filter with devider functionality

我试图实现一个过滤器,returns 一个列表以及分隔符的条目。 TextSearch 也应该适用于此过滤器。

模板:

  <input type="search" placeholder="Search" ng-model="searchText" autocorrect="off" >

  <li class="item item-checkbox" 
        ng-repeat="destination in destinations |            (a)
                destinationFilter:searchText:true"          (b) 
        ng-class="destination.letter? 'item-divider':''">   (c)

过滤器:

app.filter('myFilter', function() {
return function(input, key, startsWith) {
    if(input){
        var filteredInput = [];   (1)
        var lastChar = '';        (2)
        var re = /.*/i;           (3)
        if(key){                
            if(startsWith)        (4)
                key = "^"+key;
            re = new RegExp(key, "i");
        }
        for(var i=0; i<input.length; i++){
            var item = input[i];
            if(item.name.match(re)){                    (5)
                if(item.name.charAt(0) !== lastChar) {  (6) 
                  filteredInput.push({name:item.name.charAt(0),letter:true});
                  lastChar = item.name.charAt(0);
                }
                filteredInput.push(item);               (7)
            }
        };
        return filteredInput;                            
    }
    return input;    
};
});

不幸的是,这个过滤器经常被 30 个元素的列表调用。它还会导致此错误:

Error: [$rootScope:infdig] http://errors.angularjs.org/1.2.25/$rootScope/infdig?

我猜输入中的每个元素都添加了分隔符。看起来很奇怪。

FIDDLE: HERE

问题是您的过滤器每次调用都会生成一个新数组,这导致 angular 变成 infinite loop

您最好提供 ng-repeat 常量数组而不是函数(过滤器)。 在你的例子中,它可以简单地通过在控制器而不是视图中应用过滤器来完成(尽管你的真实情况可能不同):

$scope.filtered = $filter('destinationFilter')($scope.destinations, undefined, true);

在你的html中:

<li class="item item-checkbox" ng-repeat="destination in filtered" ng-class="destination.letter? 'item-divider':''" >

看到这个fiddle