根据价格属性的变化,我有一个经常更新的项目列表。如果商品的价格低于某个值(低于5),则该商品会被选中' property设置为true并显示在结果表中(在所选属性上过滤)。
ng-repeat="item in dataPrices | filter: {selected:true}"
我想添加一系列复选框,基于所选复选框的选择/取消选择应该进一步过滤结果 - 可以选择零到三个
<label ng-click="productType('large')">
<input type="checkbox">
<span>Large items</span>
</label>
<label ng-click="productType('small')">
<input type="checkbox">
<span>Small items</span>
</label>
<label ng-click="productType('medium')">
<input type="checkbox">
<span>Medium items</span>
</label>
我确实尝试在ng-repeat
中添加一个额外的过滤器ng-repeat="item in dataPrices | filter: {selected:true} | filter: {size:'large'}"
有效,但我不确定如何根据复选框选择/取消选择的组合结果添加这些组合。任何帮助都会非常感激。
我把这个笨蛋放在一起,这可能会让这个更清晰 - https://plnkr.co/edit/DHsOcWbfld7V7V1G8nIF?p=preview
答案 0 :(得分:1)
您应该在内置oRfilter
之后应用自定义filter : {selected: true}
:
angular.module('app', [])
.controller('ctrl', ['$scope', function($scope) {
$scope.items = [
{selected: true, size: 'large'},
{selected: false, size: 'large'},
{selected: false, size: 'medium'},
{selected: true, size: 'medium'},
{selected: true, size: 'small'}
];
$scope.search = {};
}])
.filter('oRfilter', function(){
return function(items, search){
var out = [];
var atLeastOne = false;
for(var prop in search)
if(search[prop]){
atLeastOne = true;
out = out.concat(items.filter(function(x){ return x.size == prop; }));
}
return atLeastOne ? out : items;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat='size in ["small", "medium", "large"]'>
{{size}}: <input type='checkbox' ng-model='search[size]' />
</div>
<ul>
<li ng-repeat='item in items | filter : {selected: true} | oRfilter : search'>{{item | json}}</li>
</ul>
</div>
您的plunker不起作用,因为您有两个分隔的控制器。您应该通过事件(updated plunker):
连接它们<强> navController:强>
$scope.$watchCollection('search', function(arg){
$scope.$parent.$broadcast('changed', arg);
});
<强> priceController:强>
$scope.search = {};
$scope.$on('changed', function(event, arg){
$scope.search = arg;
})
答案 1 :(得分:0)
如果你使用了很多额外的过滤器,它就不起作用,因为每个过滤器都应用于前一个过滤器的结果。 因此,如果您在执行此操作时选择“大”和“小”:{size:'large'},则结果不包含应用其他过滤器的“小”itens。
我认为你可以通过两种方式做到这一点。
1 - 您可以将函数返回到ng-repeat,它返回已过滤的列表:
ng-repeat="item in filtered()"
在您的控制器中:
$scope.filtered = function() {
//take the selected filter and your data and apply the filters
//return the filtered list
// you can code this with lodash
// $scope.data -> your data
// $scope.productType -> can be one or multiple
var filtered = _.filter($scope.data, function(item) {
//Note that this filter is just an example, this implementation depends on what you really need and how your filter selection works.
return item.selected && item.size === $scope.productType;
});
return filtered;
}
在这种情况下,您需要编写自己的过滤器并应用于列表。像lodash这样的图书馆可以为你提供很多帮助。
你也可以在ng-repeat中应用另一个过滤器:
ng-repeat="item in filtered() | anotherFilter"
2 - 您可以手动控制过滤器流量。这有点复杂,因为您需要准确了解视图应该如何工作以及何时需要更新视图。使用这种方法可以提高性能。
基本上,您将使用其他列表来接收过滤后的数据:
ng-repeat="item in filteredList"
当您需要调用函数(手动)来更新此列表时。所以
$scope.filteredList = getFilteredData();
function getFilteredData() {
return _.filter($scope.data, function(item) {
return item.selected && item.size === $scope.productType;
});
}
请注意,在此方法中,每次要更新视图时都需要调用$scope.filteredList = getFilteredData();
。因此,每次选择新的大小过滤器或类似的东西时,都需要执行代码。