Javascript 使用跟踪方式时强制拼接ng重复阵列

Javascript 使用跟踪方式时强制拼接ng重复阵列,javascript,angularjs,Javascript,Angularjs,我们的应用程序有一个任务列表,任务列表可能会非常大。主任务列表有一个侧栏,当选择任务时,可以在侧栏中对其进行编辑,侧栏使用不同的控制器(TasksSidebarCtrl而不是显示列表的TasksCtrl)。将复制选定的任务,然后将其合并回列表中。此通信在任务服务中处理 索引中每个任务的观察者数量巨大,因此我们决定采用不同的方法 使用一次性绑定已经大大减少了观察者的数量(事实上,现在创建观察者的只是编辑/更改任务状态的子菜单,而无需在侧栏中选择它),但是因为我们使用的是按任务跟踪.id(考虑到我们

我们的应用程序有一个任务列表,任务列表可能会非常大。主任务列表有一个侧栏,当选择任务时,可以在侧栏中对其进行编辑,侧栏使用不同的控制器(TasksSidebarCtrl而不是显示列表的TasksCtrl)。将复制选定的任务,然后将其合并回列表中。此通信在任务服务中处理

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

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

是否有一种方法可以强制更新此任务项,同时仍使用跟踪方式和一次性绑定?

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

TaskSidebarCtrl

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);
    });
});
$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);
});
任务服务

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');
};
使用简单的angular.copy(带目标)而不是TasksService.updateTaskIndex(vm.index,data.data)在TaskSidebarCtrlupdate函数中,表示由于一次性绑定,索引视图中的一次性绑定属性不会更新。上述操作不需要按任务跟踪。id,但如果可能的话,我不想做出这种牺牲。我也不想牺牲一次性绑定


有解决方法吗?

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


使用在条目更新时更改的
track by
表达式将删除旧任务的节点并插入一个新节点,其中一次性绑定的表达式将再次求值。一种简单的方法是使用
“{id}{version}”为任务分配
tracking\u id
属性
格式,其中版本随每次更新而变化,并使用
按任务跟踪。跟踪id

非常好的问题。你有什么例子吗?尝试复制该问题。效果很好@rishabhdev你没有使用一次性绑定-因此它可以工作。由于我任务的复杂性,使用一次性绑定势在必行需要呈现的对象和编号一次性绑定是什么意思。请编辑小提琴以显示@CIvemy@rishabhdev
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');
};