繁体   English   中英

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

[英]What is the best way to implement multiple filters 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>

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

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

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

例如,你可以将所有类似的过滤器组合成一个(我对你的任务模型的结构做了非常近似的假设:),我插入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>

我有两条建议给你。 首先,如果您想要将过滤结果放入变量中,这样您就不必再次应用所有过滤器来获取计数,您可以as filtered_result器的末尾和任何track by...之前添加as filtered_result track by...文档中描述。

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

function filterTasks(){
    var tasks = TasksCtrl.tasks;
    tasks = $filter('taskOwner')(tasks, TasksCtrl.selectedUserFilter);
    tasks = $filter('taskClient')(tasks, TasksCtrl.clientId);
    tasks = $filter('taskDepartment')(tasks, TasksCtrl.departmentId)
    tasks = $filter('taskPriority')(tasks, TasksCtrl.priority);
    tasks = $filter('taskWithClient')(tasks, TasksCtrl.withClient);
    tasks = $filter('taskEndDate')(tasks, TasksCtrl.endDate)
    tasks = $filter('filter')(tasks, {progress: 0});
    tasks = $filter('filter')(tasks, searchText);
    tasks = $filter('orderBy')(tasks, TasksCtrl.orderTasks);
    TasksCtrl.filteredTasks = tasks;
}

我建议你使用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;
    });
  }
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM