【问题标题】:AngularJS filter in nested ng-repeats嵌套 ng-repeats 中的 AngularJS 过滤器
【发布时间】:2017-07-25 16:49:37
【问题描述】:

我有 2 个嵌套的 ng-repeats 来填充这些类别下的类别和项目列表。我正在尝试实现一个搜索过滤器:

  • 如果项目的标题包含搜索过滤器的字符串,则应显示该项目及其类别。
  • 如果类别名称包含搜索过滤器的字符串,则应显示该类别。如果该类别下的项目没有匹配过滤器,则应显示该类别下的所有项目。
  • 搜索过滤器绑定到输入字段的模型。
  • 我试图实现一个自定义过滤器来循环遍历类别并根据项目的标题或类别的名称填充一个数组,但它会创建一个无限循环。

    <li data-ng-repeat="group in vars.filteredCategories = (allCategories | customFilter:filters.searchText)">
    {{group.category}}
    <ul>
    <li data-ng-repeat="item in group.items | orderBy:'title'">{{item.title}}</li>
    </ul>
    

控制器:

$scope.allCategories = [{"category":"cat1","items":[{"id":10015,"title":"Test","category":"cat1"},{"category":"cat2","items":[{"id":10015,"title":"Test2","category":"cat2"}];

自定义过滤器(不起作用)

.filter('customFilter', function () {
        return function (categories, search) {
            var filtered = [];

            var itemsPushed = [];
            if (search !== '') {
                angular.forEach(categories, function (category) {
                    if (category.category.toLowerCase().indexOf(search.toLowerCase()) !== -1) {
                        filtered.push(category);

                    } else {
                        if (angular.isDefined(category.items)) {

                            var itemsInside = angular.copy(category.items);
                            category.items = [];

                            for (var x = 0; x < itemsInside.length; x++) {
                                if (itemsInside[x].title.toLowerCase().indexOf(search.toLowerCase()) != -1 && itemsPushed.indexOf(itemsInside[x].id) == -1) {
                                    category.items.push(itemsInside[x]);
                                    itemsPushed.push(itemsInside[x].id);

                                }
                            }
                            filtered.push(category);
                        }
                    }
                });
            } else {
                filtered = categories;
            }

            return filtered;
        };
    })

【问题讨论】:

  • 我相信你的循环是因为你正在修改 category.items。您能否删除过滤器中较大的“else”部分并告诉我您是否仍然遇到该错误?
  • 感谢您的回复。如果我删除该部分,我不会循环,但它不会像我需要的那样工作。因为如果类别与过滤器不匹配,我需要它仅在它们与过滤器匹配时才将项目添加到过滤器。
  • 但是无限循环停止了吗?只是为了确定我所说的是问题所在。然后我们可以从那里开始工作
  • 是的,确实如此。对不起,我以为我在我的消息中说过,但我有一个错字。谢谢
  • 您的数据正确吗?我正在审查它的小提琴,我只看到一个具有 3 个深度级别的项目。检查 $scope.allCategories 是否写得正确

标签: javascript angularjs filter filtering


【解决方案1】:

检查这是不是你想要的http://plnkr.co/edit/zt2BJEpRv2EBbFf32rBC?p=preview

如果您想要不区分大小写的比较,可能需要修改代码。

控制器

app.controller('MainCtrl',function ($scope) {
  $scope.filterText = '';
  $scope.data = [
    {"category":"cat1",
      "items":[{"id":10015,"title":"Test","category":"cat1"}, {"id":10015,"title":"Other","category":"cat1"}]
    },
    {"category":"cat2",
      "items":[{"id":10015,"title":"Test2","category":"cat2"}]
    }];
});

过滤器

app.filter('customFilter', function(){
  return function(data, searchString) {
    if (searchString === '') {
      return data;
    }
    // don't modify original state
    var newData = [];
    data.forEach(function(group){
      // If the name of the category contains the string of the search filters, 
      // this category should be displayed. If non of the items under this category match the filter,
      // all the items under the category should be displayed.
      var matchCategory = group.category.indexOf(searchString) > -1;
      var nonItemMatches = group.items.every(function(item){
        return item.title.indexOf(searchString) === -1;
      });
      if (matchCategory || nonItemMatches) {
        newData.push(group);
        return
      }
      // If the title of an item contains the string of the search filter,
      // this item and its category should be displayed.
      var groupCustomItems = angular.extend({}, group);
      groupCustomItems.items = [];
      group.items.forEach(function(item) {
        if (item.title.indexOf(searchString) > -1) {
          groupCustomItems.items.push(item);
        }
      });
      if (groupCustomItems.items.length) {
        newData.push(groupCustomItems);
      }
    });
    return newData;
  };
});

查看

<input type="text" ng-model="filterText" />
  <ul>
    <li ng-repeat="group in data | customFilter:filterText">
      {{ group.category }}
      <ul>
        <li ng-repeat="item in group.items">
          {{ item.title }} 
        </li>
      </ul>
  </ul>

我不得不假设您的数据是错误的,因为它与您的 html 视图不匹配

您可能想阅读filter 文档

【讨论】:

  • 非常感谢!这正是我想要的。非常感谢您抽出宝贵时间。
猜你喜欢
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多