AngularJS复选框过滤器

时间:2014-06-01 18:57:07

标签: angularjs checkbox angularjs-directive angular-ngmodel angular-filters

我想过滤结果。

有一份葡萄酒清单,我的愿望是当没有勾选复选框时,会显示整个葡萄酒清单。

  • 当仅选中1个复选框时,显示相关类别
  • 当选中多个复选框时,将显示相关类别

我是AngularJS的新手,我尝试使用ng-model但没有成功,这里是没有与该函数关联的ng-model的代码:

<html ng-app="exampleApp">
<head>
    <title></title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.10/angular.min.js"></script>

    <script>
        angular.module("exampleApp", [])
                .controller("defaultCtrl", function ($scope) {
                    $scope.wines = [
                        { name: "Wine A", category: "red" },
                        { name: "Wine B", category: "red" },
                        { name: "wine C", category: "white" },
                        { name: "Wine D", category: "red" },
                        { name: "Wine E", category: "red" },
                        { name: "wine F", category: "white" },
                        { name: "wine G", category: "champagne"},
                        { name: "wine H", category: "champagne" }

                    ];


                    $scope.selectItems = function (item) {
                        return item.category == "red";
                    };

                    $scope.selectItems = function (item) {
                        return item.category == "white";
                    };

                    $scope.selectItems = function (item) {
                        return item.category == "champagne";
                    };
                });
    </script>
</head>
<body ng-controller="defaultCtrl">

<h4>red: <input type="checkbox"></h4>
<h4>white: <input type="checkbox"></h4>
<h4>champagne: <input type="checkbox"></h4>



            <div ng-repeat="w in wines | filter:selectItems">
                {{w.name}}
                {{w.category}}
            </div>


</body>
</html>

如何使用ng-model或ng-change将函数关联到每个复选框按钮以获得实时过滤模型?

3 个答案:

答案 0 :(得分:46)

有几种可能的实现方式。这是一个:

  1. 拥有一个$scope.filter = {}对象来保存每个过滤器的状态。例如。 {red: true, white: false...}

  2. 使用ng-model将每个复选框与相应的属性相关联。例如:input type="checkbox" ng-model="filter['red']" />

  3. 有一个函数(例如$scope.filterByCategory(wine))决定是否应该显示葡萄酒(基于$scope.filter对象)。

  4. 使用该功能根据类别过滤项目。例如。 <div ng-repeat="wine in wines | filter:filterByCategory">


  5. filterByCategory函数可以像这样实现:

    function filterByCategory(wine) {
      // Display the wine if
      var displayWine =
          // the wine's category checkbox is checked (`filter[category]` is true)
          $scope.filter[wine.category] ||   // or 
    
          // no checkbox is checked (all `filter[...]` are false)
          noFilter($scope.filter);
    
      return displayWine;
    };
    

    其中noFilter()是一个检查是否有激活过滤器的函数(如果没有则返回true):

    function noFilter(filterObj) {
      return Object.
        keys(filterObj).
        every(function (key) { return !filterObj[key]; });
    }
    

    另请参阅此 short demo


    <强>更新

    我创建了一个修改版本,它支持多个过滤器(不仅仅按类别过滤) 基本上,它动态检测可用属性(基于第一个wine元素),添加控件(复选框组)以根据每个属性应用过滤器,并具有以下自定义过滤器功能:

    1. 根据每个属性过滤每个wine项目。
    2. 如果某个属性未应用过滤器(即未选中复选框),则会将其忽略。
    3. 如果某个属性选中了复选框,则会用于过滤掉wine个项目(参见上文)。
    4. 有使用AND应用多个过滤器的代码(即所有属性必须匹配)或OR(至少一个属性必须匹配)。

    5. 另请参阅此 updated demo

答案 1 :(得分:1)

我更喜欢将filter用作$filter

app.filter('someFilter',checkboxFilter)
checkboxFilter() {
    return function (arr,filter,key,noOne=false) {
        // arr is an array of objects
        // filter is checkbox filter. someting like {1:true,2:false}
        // key is a property in ech object inside arr
        // noOne is a behavior if none of checkbox is activated (default:false)
        if (!arr.length) return null;

        function noOneCheck(filter) {
            return Object.keys(filter).every((key) => {
                return !filter[key]
            })
        }
        return arr.filter((i) => {
            return filter[i[key]] || (noOne && noOneCheck(filter))
        })
    }
};

<强> HTML:

ng-repeat="u in project.projectTeamInvite | checkbox:project.status:'status' track by $index">

答案 2 :(得分:1)

只需添加到@gkalpak答案,我发现这个codepen允许您提供为每个类别选择选项后剩余的总金额。

从以下位置更改ng-repeat

<div ng-repeat="wine in (ctrl.wines | filter:ctrl.filterByProperties) as filteredWines">
      {{ wine.name }} <i>({{ wine.category }})</i>
</div>

收件人

<div ng-repeat="wine in filtered = (ctrl.wines | filter:ctrl.filterByProperties) as filteredWines">
  {{ wine.name }} <i>({{ wine.category }})</i>
</div>

并在输入标签上添加:

<label>
    <input type="checkbox" ng-model="ctrl.filter[prop][value]" />
    {{ value }}({{(filtered | filter:value:true).length}})
</label>