使用knockoutjs进行周期性观察

时间:2016-03-01 19:10:31

标签: javascript mvvm knockout.js

我有一个视图,如下图所示:

enter image description here

点击视图列中的项目后,将填充可用列列表。当用户点击 Views 列表中的其他项目时,需要重置可用列列表,并使用与新选择的视图相关的列填充

在我的淘汰视图模型中,我有以下订阅和计算:

self.columnsToAdd.subscribe(function (items) {
    var viewIndex = findViewIndex(self.selectedView().ViewId);
    //delete columns from the selected view then add in those that are in the 
    //columnsToAdd list
    data.Users[0].Views[viewIndex].VisibleColumns.length = 0;
    for (i = 0; i < items.length; i++) {
        data.Users[0].Views[viewIndex].VisibleColumns.push(view = {ColumnId:items[i].ColumnId, Heading:items[i].Heading});
    }
});

self.selectedView.subscribe(function (item) {
    //clear columnsToAdd then re-populate
    //this line is causing data.Users[0].Views[0].VisibleColumns to be reset
    //because it triggers the columnsToAdd.Subscribe
    self.columnsToAdd([]); 
    var view = getById(self.views, item.ViewId);
    for (i = 0; i < view.VisibleColumns.length; i++) {
        self.columnsToAdd.push(view.VisibleColumns[i]);
    }
});

self.allColumns = ko.computed(function () {
    var view = getById(self.views, self.selectedView().ViewId);
    return view ? ko.utils.arrayMap(view.AllColumns, function (item) {
        return {
            ColumnId: item.Id,
            Heading: item.Heading
        };
    }) : [];
}, this);

从我的代码注释中可以看出,问题在于订阅 selectedView observable。这绑定到 Views 的选定项目  名单。当这个更改时,我需要清除 Available Columns 列表,但这会导致绑定的observable数组的订阅触发,然后清除 VisibleColumns 可观察数组, selectedView订阅。

是否有标准模式用于解决knockoutjs的问题?

1 个答案:

答案 0 :(得分:0)

我的解决方案是删除 columnsToAdd 可观察数组的订阅。相反,我在添加删除的事件中更新 Views 集合的后备视图模型的 VisibleColumns 集合按钮:

self.addColumn = function () {
        if (self.columnsToAdd().indexOf(self.selectedAvailableColumn()) < 0) {
            self.columnsToAdd.push(self.selectedAvailableColumn());
            data.Users[0].Views[self.viewIndex].VisibleColumns.push(self.selectedAvailableColumn())
        }
    };

    self.removeColumn = function () {
        self.columnsToAdd.remove(self.selectedColumnToRemove());
        data.Users[0].Views[self.viewIndex].VisibleColumns.pop(self.selectedAvailableColumn())
    };