AngularJS Unique Filter然后更新所有记录

时间:2013-06-20 03:13:06

标签: javascript angularjs angular-ui

我的任务是使用AngularJS显示记录列表,如下所示:

$scope.colours = [
  {id:'1', name: 'red', active: true },
  {id:'2',  name: 'blue', active: false },
  {id:'3',  name: 'green', active: true },
  {id:'4',  name: 'red', active: false }
];

并允许用户通过其所在类别(或示例颜色)的复选框显示/隐藏它们。所以我使用Angular-UI Unique过滤器获取了数据并显示了一些复选框,但当我切换“红色”类别时,我想切换所有以“红色”作为值的记录。

我猜我需要遍历记录并手动对复选框进行更改是否有更多Angular方法来执行此操作?

即使使用角度滤镜来过滤大型数据集的ng-repeat结果,这也是一种很好的做法吗?

查看小提琴http://jsfiddle.net/sjmcpherso/QXk9E/

此致

2 个答案:

答案 0 :(得分:1)

您可以使用按多个值排序的自定义过滤器。这样您就可以从所有数据中删除active属性。我们称之为manyToMany并让它有三个参数:

  1. 要排序的对象数组
  2. 一个字符串,用于指定要按
  3. 排序的对象上的哪个属性
  4. 布尔属性的对象哈希,其键与属性的可能值相关联。如果sort属性应包含与该键匹配的结果,则任何给定属性的值将为true
  5. 以下是过滤器的样子:

    .filter('manyToMany',function(){
        return function(arrInput,strProperty,objMany){
            var arrFiltered = [];
            for(var i=0,max=arrInput.length;i<max;i++){
                if(objMany[arrInput[i][strProperty]] === true){
                    arrFiltered.push(arrInput[i]);
                }
            };
            return arrFiltered;
        }
    });
    

    然后在范围中创建一个新对象,用于objMany

    $scope.activeColors = {};
    

    在HTML中,让复选框根据唯一转发器中的颜色名称设置该对象的值:

    <input type="checkbox" ng-model="activeColors[colour.name]" />{{colour.name}}
    

    并使用过滤器:

    <div ng-repeat="colour in colours | manyToMany:'name':activeColors">{{colour}}</div> 
    

    Here is a fiddle

答案 1 :(得分:0)

首先,您的模型不正确。您需要的是用户根据条件过滤的项目列表 - 在本例中为颜色。

在这种情况下,不应将active属性放在每个对象上。相反,你应该做的是以下几点:

第1步
将模型定义为:

$scope.colors = [
    {
        id: 1,
        name: "red"
    },
    {
        id: 2,
        name: "blue"
    },
    {
        id: 3,
        name: "green"
    },
    {
        id: 4,
        name: "red"
    }
];

请注意,我尚未向每个对象添加active属性。

第2步
接下来,您定义另一个跟踪活动过滤器的模型:

$scope.activeFilters = [];

最初,这将是空的,但是根据每个过滤器的选择状态,它将被添加/删除。

第3步 然后,您有一个函数将通知复选框是否处于活动状态

$scope.isChecked = function (item) {
    return $scope.activeFilters.indexOf(item) !== -1;
};

第4步
然后定义一个将添加/删除过滤器项的函数:

$scope.toggleFilter = function (filterItem) {
    //Check if the filter item already exists in the list of active filters
    if ($scope.activeFilters.indexOf(filterItem) !== -1) {
        //Yes, the filter item already exists.
        //Since we are in toggle mode, we remove the item from the active filters
        $scope.activeFilters.splice($scope.activeFilters.indexOf(filterItem), 1);
    } else {
        //No entry does not exist.
        //Since we are in toggle mode, we add the entry to the list
        $scope.activeFilters.push(filterItem);
    }
};

每次设置/取消设置任何复选框时,都可以调用此功能。

第5步
接下来,您将定义一个基于活动过滤器设置过滤器数据的函数:

$scope.filterData = function () {
    //This will be the model that will be used to display the final or
    //filtered data
    //Reset it each time this is called
    $scope.filteredColors = [];

    //If there are no active filters, show all the colors
    if ($scope.activeFilters.length === 0) {
        $scope.filteredColors = $scope.colors;
    } else {
        for (var i = 0; i < $scope.colors.length; i++) {
            //Check if the color name is requested in the active filter
            if ($scope.activeFilters.indexOf($scope.colors[i].name) !== -1) {
                //The color has been actively set in the filter. Display it
                $scope.filteredColors.push($scope.colors[i]);
            }
        }
    }
};

//When the controller is initialized, we need to call the above function once to
//get the colors to display. Since no filters are active initially, all colors
//will be shown
$scope.filterData();

第6步
每次活动过滤器更改时,您需要重新计算要显示的颜色 - 一个简单的手表就足够了

$scope.$watch('activeFilters.length', function () {
    //Check for invalid values
    if ($scope.activeFilters === null || $scope.activeFilters === undefined) {
        //Nothing to do
        return;
    } else {
        //Re-calculate the colors to display
        $scope.filterData();
    }
});

因此,每次设置/重置滤镜时,都会重新计算要显示的颜色列表。

第7步
您现在需要一个包含唯一颜色的模型 - 用于过滤器

$scope.uniqueColors = [];

for (var j = 0; j < $scope.colors.length; j++) {
    if ($scope.uniqueColors.indexOf($scope.colors[j].name) === -1) {
        //The color does not exist. Add it
        $scope.uniqueColors.push($scope.colors[j].name);
    }
}

最后一步
视图 - 基于我们之前定义的模型和函数,您现在需要相应地定义视图。

<label ng-repeat="c in uniqueColors">
    <input type="checkbox" ng-checked="isChecked(c)" ng-click="toggleFilter(c)">
    {{c}}
</label>

<div ng-repeat="f in filteredColors">
    {{f}}
</div>

编辑:Here是一个小提琴。