What is the best way to implement multiple AngularJS filters?

I have several filters working perfectly on ng-repeat. However, the code seems unnecessarily long for the actual action of the filters on the set, and I wonder if there is a better way.

Here is an example filter - this bit is fine with me (if anyone has no advice) - they all follow a similar structure:

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; } }) 

And, as I said, there are several. Then, on my ng-repeat, I implement them as such ( , this is a bit that seems complicated to maintain and is too long, and would be appreciated by information on any best practices ):

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

Judging by how many scrolls are here, I think you can see my problem with the above code. In order to view the duration of tasks (also divided into completed, in progress, etc.), I must select all the filters again.

Is there a better way to implement these filters?

I am also concerned that after reading this article I don’t understand the difference between state filters and non-statistical ones - are these filters optimized for performance above?

+5
source share
3 answers

you can combine all your similar filters into one, for example (I made very rough assumptions about the structure of your task model :), I inserted a filter: {progress: 0} inside the 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 may now look like

 <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> 
+3
source

I have two tips for you. Firstly, if you want to get the filtered result in a variable, so you do not need to apply all the filters again to get the invoice, you can add as filtered_result at the end of your filters and before any track by... , as described in the documentation .

Another tip to you is not to force the use of filters in HTML. In your case, it might be better to create a function that will filter your TasksCtrl.tasks once and save the results in the TasksCtrl.filteredTasks property, which your ng-repeat can repeat with less hours. If you want to save the filtering code in Angular filters, you can enter $filter and run them manually in your function.

 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; } 
+3
source

I suggest you use the javascript filter() function, which is really efficient:

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

All Articles