实现多个过滤器AngularJS的最佳方法是什么?

时间:2016-09-07 09:10:01

标签: javascript angularjs

我有多个过滤器在ng-repeat上工作正常。但是,代码似乎没有多长时间来实际操作集合上的过滤器,我想知道是否有更好的方法。

这是一个示例过滤器 - 这一点我没关系(除非有人有任何建议) - 它们都遵循类似的结构:

app.js

.filter('taskClient', function() {
    return function (items, clientId) {
        if (!clientId) { return items; }
        var filtered = [];
        angular.forEach(items, function(item) {
            if (item.client) {
                if (item.client.id === clientId) {
                    filtered.push(item);
                }
            }
        });
        return filtered;
    }
})

正如我所说 - 其中有几个。然后,在我的ng-repeat上,我实现它们(这似乎很难维护并且过长,并且会欣赏有关任何更好技术的信息):

任务-的index.html

<md-list-item icp-task-line ng-repeat="task in TasksCtrl.tasks | taskOwner: TasksCtrl.selectedUserFilter | taskClient: TasksCtrl.clientId | taskDepartment: TasksCtrl.departmentId | taskPriority: TasksCtrl.priority | taskWithClient: TasksCtrl.withClient | taskEndDate: TasksCtrl.endDate | filter: {progress: 0} | filter: searchText | orderBy: TasksCtrl.orderTasks" class="md-2-line"></md-list-item>

根据这里涉及的滚动量来判断,我想你可以通过上面的代码看到我的问题。为了获得视图中的任务长度(也分为已完成,正在进行等),我必须再次列出所有过滤器。

有没有更好的方法来实现这些过滤器?

我还担心在阅读this article之后我不理解有状态和无状态过滤器之间的区别 - 以上过滤器是针对性能进行了优化的吗?

3 个答案:

答案 0 :(得分:4)

你可以将所有类似的过滤器组合成一个,例如(我对任务模型的结构做了非常近似的假设:),我也插入了filter: {progress: 0}过滤器:

.filter('taskFilter', function() {
  return function (items, args) {
    return items.filter(function(item) {
      return (!args.selectedUserFilter || item.selectedUserFilter === args.selectedUserFilter) &&
             (!args.clientId || item.client && item.client.id === args.clientId) &&
             (!args.departmentId || item.department && item.department.id === args.departmentId) &&
             (!args.priority || item.priority === args.priority) &&
             (!args.withClient || item.withClient === args.withClient) &&
             (!args.endDate || item.endDate === args.endDate) &&
             item.progress === 0;
    });
  }
})

现在HTML可能看起来像

<md-list-item icp-task-line ng-repeat="task in TasksCtrl.tasks | taskFilter: TasksCtrl | filter: searchText | orderBy: TasksCtrl.orderTasks" class="md-2-line"></md-list-item>

答案 1 :(得分:3)

我有两条建议给你。首先,如果您希望将过滤结果放入变量中,这样您就不必再次应用所有过滤器来获取计数,您可以在过滤器末尾和任何{{1}之前添加as filtered_resultdocumentation

中所述

我的另一个建议是不要强制在HTML中使用过滤器。在您的情况下可能更好,以创建一个过滤track by... 一次的功能,并将结果保存到TasksCtrl.tasks属性中-repeat可以用更少的手表迭代。如果要将过滤代码保留在Angular过滤器中,可以注入TasksCtrl.filteredTasks并在函数中手动运行它们。

$filter

答案 2 :(得分:0)

我建议您使用javascript函数filter(),它非常强大:

.filter('taskClient', function() {
  return function(items, clientId) {
    if (!clientId) { return items; }
    return items.filter(function(item) {
      return item.client && item.client.id === clientId;
    });
  }
})