时间:2016-09-26 15:17:28

标签: javascript angularjs

我们的应用程序有一个任务列表,可能会变得非常大。主要任务列表有一个侧边栏,当选择任务时,可以在侧边栏中编辑它 - 它使用不同的控制器(TasksSidebarCtrl而不是显示列表的TasksCtrl)。复制所选任务,然后将其合并回列表。此通信在 TasksService

中处理

索引中每个任务的观察者数量巨大,因此我们决定采用不同的方法。

使用一次性绑定大大减少了观察者的数量(事实上,它只是编辑/更改任务状态的子菜单,而不是在现在创建观察者的侧栏中选择它),但因为我们正在使用 track by task.id (我认为考虑到我们拥有的过滤器数量以及DOM更改频率的必要性),使用splice不会删除并用新更新的任务替换任务 - 我理解是完整的跟踪点。

有没有办法强制更新此任务项目仍然使用跟踪和一次性绑定?

tasks-index.html (我删除了过滤器以提高可读性)

<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) {
        /* Using copy here so index view does not update as we edit */
        vm.selectedTask = angular.copy(newVal);
        vm.index = TasksService.getSelectedTaskIndex();

    }
});

TasksService.update(vm.selectedTask).then(function(data) {
    // notifications etc here, then...
    TasksService.updateTaskInIndex(vm.index, data.data);
});

TasksService

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

在TaskSidebarCtrl 更新功能中使用简单的angular.copy(带目标)代替 TasksService.updateTaskInIndex(vm.index,data.data)意味着一个由于一次性绑定,因此在索引视图中不会更新时间绑定属性。以上工作没有 track by task.id ,但如果可能,我不想做出这样的牺牲。我也不想牺牲一次性约束力。

有解决方法吗?

1 个答案:

答案 0 :(得分:1)

由于track by task.id获得新更新任务的相同值,因此不会重建条目的DOM元素,并且由于一次性绑定,此现有元素中的表达式不会更新。

使用在更新条目时更改的track by表达式将删除旧任务的节点并插入新节点,其中将再次评估一次性绑定表达式。一种简单的方法是为任务分配tracking_id属性"{id}_{version}"格式,其中版本随每次更新而更改,并使用track by task.tracking_id