1

我的任务是使用 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 方法可以做到这一点?

对于大型数据集,甚至使用 Angular 过滤器过滤掉 ng-repeat 中的结果,这也是一种很好的做法吗?

见小提琴http://jsfiddle.net/sjmcpherso/QXk9E/

问候

4

2 回答 2

1

您可以使用按多个值排序的自定义过滤器。这也将允许您active从所有数据中删除该属性。让我们调用它manyToMany并让它接受三个参数:

  1. 要排序的对象数组
  2. 一个字符串,用于指定这些对象上要排序的属性
  3. 布尔属性的对象哈希,其键与属性的可能值相关。任何给定属性的值将是true排序属性是否应包含与该键匹配的结果。

这是过滤器的样子:

.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> 

这是一个小提琴

于 2013-06-20T05:24:47.277 回答
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>

编辑:是一个相同的小提琴。

于 2013-06-20T05:29:56.693 回答