Our application has a list of tasks that can grow quite large. The main task list has a side panel, and when a task is selected, it can be edited on the side panel, which uses a different controller (TasksSidebarCtrl, not TasksCtrl, which displays the list). The selected task is copied and then combined into a list again. this connection is processed in the TasksService .
The number of observers for the assignment in the index was huge, so we decided to use a different approach.
The use of one time reference was significantly reduced to the number of observers (in fact, this is only a submenu for editing / changing the status of a task, not selecting it in the sidebar, which now creates observers), but because we use track by task.id (which I I consider it as a necessity, given the number of filters that we have and how often the DOM changes), the use of splicing does not remove or replace the task with a new updated task - what do I understand the essence of the goal.
Is there a way to force this whist task item to be updated while still using both tracking and one-time binding?
tasks-index.html (I removed the filters to make reading easier)
<md-list-item my-task-directive ng-repeat="task in TasksCtrl.tasks track by task.id">
TasksCtrl
TasksService.index().then(function(tasks) { vm.tasks = tasks.data ? tasks.data : []; }); $scope.$on('task-updated', function() { var newTask = TasksService.getUpdatedTask(); $timeout(function() { vm.tasks.splice(newTask.index, 1, newTask.task); }); });
TaskSidebarCtrl
$scope.$watch(function() { return TasksService.getSelectedTask(); }, function (newVal, oldVal) { if (newVal !== oldVal) { vm.selectedTask = angular.copy(newVal); vm.index = TasksService.getSelectedTaskIndex(); } }); TasksService.update(vm.selectedTask).then(function(data) {
Taskservice
var selectedTask = {}; var indexOfTask; var updatedTask = {}; var updatedIndex; this.setSelectedTask = function(task, index) { selectedTask = task; indexOfTask = index; }; this.getSelectedTask = function() { return selectedTask; }; this.getSelectedTaskIndex = function() { return indexOfTask; }; this.getUpdatedTask = function() { return { 'index': updatedIndex, 'task': updatedTask }; }; this.updateTaskInIndex = function(index, task) { updatedTask = task; updatedIndex = index; $rootScope.$broadcast('task-updated'); };
Using simple angular.copy (with purpose) instead of TasksService.updateTaskInIndex (vm.index, data.data) in the TaskSidebarCtrl update function means that one-time related properties are not updated in the index view due to a single binding. The above works without the task.id track , but I do not want to make this sacrifice, if possible. I also do not want to sacrifice a one-time binding.
Is there a workaround?