从选择/取消选择复选框组合中过滤ng-repeat列表项目

问题描述:

我有一个基于价格属性更改而经常更新的项目列表。如果物品的价格低于特定值(低于5),则该物品的“selected”属性设置为true,并显示在结果表中(在所选属性上进行过滤)。从选择/取消选择复选框组合中过滤ng-repeat列表项目

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-重复

ng-repeat="item in dataPrices | filter: {selected:true} | filter: {size:'large'}" 

其工作原理,但我不知道如何根据CHEC的组合的结果,加上它们的组合kbox选择/取消选择。任何帮助将不胜感激。

我已经把这个plunkr在一起这可能使这一点更清楚 - 因为以前的过滤器的结果应用于每一个过滤器https://plnkr.co/edit/DHsOcWbfld7V7V1G8nIF?p=preview

如果你使用了很多额外的过滤器,它ins't工作, 。 所以,当你这样做时,如果你选择'大'和'小':{尺寸:'大'},结果不包含'小'来应用另一个过滤器。

我认为你可以通过两种方式做到这一点。

1 - 你可以返回一个功能,您的NG-重复,返回过滤列表:

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-重复过应用其他过滤器:

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();。所以每次你选择一个新的尺寸过滤器或类似的东西,你需要执行代码。

你应该申请后定制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不工作,因为你有两个分离控制器。

navController:

$scope.$watchCollection('search', function(arg){ 
    $scope.$parent.$broadcast('changed', arg); 
}); 

priceController:

$scope.search = {}; 
$scope.$on('changed', function(event, arg){ 
    $scope.search = arg; 
}) 
+0

嗨感谢这个你应该通过事件(updated plunker)连接它们。从概念上讲,我认为它很接近,但是当我改编自己的代码时,它似乎不工作 - 请参阅更新的plunkr,https://plnkr.co/edit/WgHQj4rbU3jgMMHNh81i?p=preview –

+1

@JaneDelugas,查看更新的答案。 –

+0

非常感谢。我个人觉得我从这方面学到了很多东西!再次感谢 : ) –