自定义过滤器函数

在我的控制器中,我想过滤一个对象数组。这些对象中的每一个都是一个既可以包含字符串又可以包含列表的映射

我尝试使用 $filter('filter')(array, function)格式,但是我不知道如何访问函数中数组的单个元素。这里有一个片段来展示我想要的。

$filter('filter')(array, function() {
return criteriaMatch(item, criteria);
});

然后在 criteriaMatch()中,我将检查每个属性是否匹配

var criteriaMatch = function(item, criteria) {
// go thro each individual property in the item and criteria
// and check if they are equal
}

我必须在控制器中完成所有这些操作,然后编译一个列表列表,并在作用域中设置它们。所以我只需要通过这种方式访问 $filter('filter')。到目前为止,我在网络中找到的所有例子在函数内部都有静态条件搜索,它们不会传递一个条件对象并针对数组中的每个条目进行测试。

132335 次浏览

You can use it like this: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview

Like you found, filter accepts predicate function which accepts item by item from the array. So, you just have to create an predicate function based on the given criteria.

In this example, criteriaMatch is a function which returns a predicate function which matches the given criteria.

template:

<div ng-repeat="item in items | filter:criteriaMatch(criteria)">
\{\{ item }}
</div>

scope:

$scope.criteriaMatch = function( criteria ) {
return function( item ) {
return item.name === criteria.name;
};
};

Additionally, if you want to use the filter in your controller the same way you do it here:

<div ng-repeat="item in items | filter:criteriaMatch(criteria)">
\{\{ item }}
</div>

You could do something like:

var filteredItems =  $scope.$eval('items | filter:filter:criteriaMatch(criteria)');

Here's an example of how you'd use filter within your AngularJS JavaScript (rather than in an HTML element).

In this example, we have an array of Country records, each containing a name and a 3-character ISO code.

We want to write a function which will search through this list for a record which matches a specific 3-character code.

Here's how we'd do it without using filter:

$scope.FindCountryByCode = function (CountryCode) {
//  Search through an array of Country records for one containing a particular 3-character country-code.
//  Returns either a record, or NULL, if the country couldn't be found.
for (var i = 0; i < $scope.CountryList.length; i++) {
if ($scope.CountryList[i].IsoAlpha3 == CountryCode) {
return $scope.CountryList[i];
};
};
return null;
};

Yup, nothing wrong with that.

But here's how the same function would look, using filter:

$scope.FindCountryByCode = function (CountryCode) {
//  Search through an array of Country records for one containing a particular 3-character country-code.
//  Returns either a record, or NULL, if the country couldn't be found.


var matches = $scope.CountryList.filter(function (el) { return el.IsoAlpha3 == CountryCode; })


//  If 'filter' didn't find any matching records, its result will be an array of 0 records.
if (matches.length == 0)
return null;


//  Otherwise, it should've found just one matching record
return matches[0];
};

Much neater.

Remember that filter returns an array as a result (a list of matching records), so in this example, we'll either want to return 1 record, or NULL.

Hope this helps.