【问题标题】:angular ng-options select filter ng-repeat角度 ng-options 选择过滤器 ng-repeat
【发布时间】:2016-07-07 15:29:17
【问题描述】:

我正在重写一个角度选择选项,以前我使用的是带有许多 li 类的引导 btn-group 类,它使用 ng-click 在我的 ng-repeat 列表中设置一个过滤器,效果很好。像这样:

<li role="menuitem">
   <a ng-click="myFilter = { moving: true }">Delivery &amp; Removals</a>
</li>

但是,经过一些反馈后,我被要求将其更改为 &lt;select&gt; 并设置 &lt;option&gt;,以反映所选选项。

我已将一个列表添加到我的控制器范围,如下所示:

$scope.taskCategories = [
    {'cat': 'Moving & Delivery', 'filter': 'moving: true'},
    {'cat': 'DIY', 'filter': 'DIY: true'},
    {'cat': 'Marketing', 'filter': 'marketing: true' }
]

这里是选择

{{ selectedCat.filter }}
<select ng-model="selectedCat" ng-value="x.filter" ng-options="x.cat for x in taskCategories">
  </select>

这是我的 ng-repeat

data-ng-repeat="task in vm.tasks | filter:search | filter:myFilter | filter: { filter: selectedCat.filter } : true | orderBy:predicate:reverse | filter:x as results" 

为了提供一点相关性,我的 ng-click 过滤器是这样工作的:

ng-click="myFilter = { moving: true }"

但是,当我单击通过 $scope.taskCategories 进行 ng-repeat 的选择值之一时,我的 ng-repeat 返回 0 个结果,这是不正确的。

如果有人能指出我哪里出错了,我将不胜感激。提前致谢! :)

【问题讨论】:

标签: angularjs angularjs-ng-repeat ng-options angular-filters


【解决方案1】:

您可以创建自定义过滤器并通过对象内部的属性进行搜索,如下所示:

(function(angular) {
  'use strict';
angular.module('ngRepeat', ['ngAnimate'])
.controller('repeatController', function($scope) {
  $scope.tasks = [
  			{
        'created': "2016-07-02T21:01:56.095Z",
        'description':"hang it",
        'dueDate':"2016-07-02T22:00:00.000Z",
        'inPersonTask':true,
        'isCurrentUserOwner':false,
        'moving':true,
        'profileImageURL':"modules/users/client/img/profile/default.png",
        'statusAssigned':false,
        'statusClosed':false,
        'statusOpen':true,
        'taskLocation':"eerywhere",
        'title':'example 3'
        },
        {
        'created': "2016-07-02T21:01:56.095Z",
        'description':"hang it",
        'dueDate':"2016-07-02T22:00:00.000Z",
        'inPersonTask':true,
        'isCurrentUserOwner':false,
        'DIY':true,
        'profileImageURL':"modules/users/client/img/profile/default.png",
        'statusAssigned':false,
        'statusClosed':false,
        'statusOpen':true,
        'taskLocation':"the world",
        'title':'example 2'
        },
        {
        'created': "2016-07-02T21:01:56.095Z",
        'description':"hang it",
        'dueDate':"2016-07-02T22:00:00.000Z",
        'inPersonTask':true,
        'isCurrentUserOwner':false,
        'marketing':true,
        'profileImageURL':"modules/users/client/img/profile/default.png",
        'statusAssigned':false,
        'statusClosed':false,
        'statusOpen':true,
        'taskLocation':"the world",
        'title':'example 3'
        }
  ];
  $scope.taskCategories = [
        {'cat': 'Moving & Delivery', 'filter': 'moving: true'},
        {'cat': 'DIY', 'filter': 'DIY: true'},
        {'cat': 'Marketing', 'filter': 'marketing: true' }
    ];
})

  .filter('customFilter', function() {
    return function(items, search) {
      if (!search) {
        return items;
      }    

      return items.filter(function(element) {
       // Ex: moving: true, becomes just 'moving'
       return Object.getOwnPropertyNames(element).find(x => x == search.substring(0, search.indexOf(':')));
      });
    };
  });
})(window.angular);
.example-animate-container {
  background:white;
  border:1px solid black;
  list-style:none;
  margin:0;
  padding:0 10px;
}

.animate-repeat {
  line-height:30px;
  list-style:none;
  box-sizing:border-box;
}

.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
  transition:all linear 0.5s;
}

.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
  opacity:0;
  max-height:0;
}

.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
  opacity:1;
  max-height:30px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Example</title>
  <link href="animations.css" rel="stylesheet" type="text/css">
   <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.min.js"></script>
</head>

<body ng-app="ngRepeat">
  <div ng-controller="repeatController">
    <!-- list of tasks /-->
    <h3>List of tasks, without filter</h3>
    <ul class="example-animate-container">
      <li class="animate-repeat" ng-repeat="task in tasks">[{{$index + 1}}] {{ task.title }}, {{ task.taskLocation }}</li>
    </ul>
    <!-- list of tasks with filter /-->
    <h3>List of tasks with filter -- results are not showing</h3>
    <p>{{ selectedCat }}</p>
    <select ng-model="selectedCat" ng-options="x.cat for x in taskCategories" ng-value="x.filter">
    </select>
    <ul>
      <li class="animate-repeat" ng-repeat="task in tasks | customFilter: selectedCat.filter">
        [{{$index + 1}}] {{ task.title }}, {{ task.taskLocation }}</li>
    </ul>
  </div>
</body>

</html>

【讨论】:

  • 非常感谢您的帮助,我现在就试试这个,让您尽快知道我的情况:)
  • 可以查看上面的sn-p。
  • 对不起,我只需要在本地测试。非常感谢!像魅力一样工作。我已标记为已接受的答案。再次感谢!
  • 很抱歉再次打扰您 - 我在使用 => 箭头函数时遇到错误,您建议如何重写 find(x => x == search.substring(0, search.indexOf(' :'))); ?再次感谢!
  • 嗯.. 你正在编译你的 JS 文件,对吧?更改很简单:return Object.getOwnPropertyNames(element).find(function(x) { return x == search.substring(0, search.indexOf(':')) });