具有敲除发布/订阅的可观察数组

时间:2013-04-30 19:24:16

标签: knockout.js publish-subscribe single-page-application

我关注这篇文章:

http://www.knockmeout.net/2012/05/using-ko-native-pubsub.html

允许我的一个vms与另一个vms通信。我的一个viewModels有一个我需要向另一个viewModel公开的数组。如果这个数组不是一个可观察的,那么上面帖子中的方法就可以了。

如果数组是可观察数组,则永远不会填充publishedSelectedFolders。我试图找出原因;希望这是我做的傻事。

这是我的jsFiddle:

http://jsfiddle.net/PTSkR/40/

如果取消注释vm中的行,它将按预期工作(在检查勾选时填充publishedSelectedFolders)。为什么会这样?

代码:

    /*
 * Pub/Sub (decouples VMs but lets them access each others' data)
 */
var postbox = new ko.subscribable();

ko.subscribable.fn.publishOn = function (topic) {
    this.subscribe(function (newValue) {
        postbox.notifySubscribers(newValue, topic);
    });

    return this; //support chaining
};

ko.subscribable.fn.subscribeTo = function (topic) {
    postbox.subscribe(this, null, topic);
    return this; //support chaining
};

/* Selection code */
this.publishedSelectedFolders = ko.observableArray().subscribeTo("SELECTED_FOLDERS");

var vm = {
    folders: ko.observableArray([{
        "folderId": "1"
    }, {
        "folderId": "2"
    }]),
    // folders: [{"folderId": "1"}, {"folderId": "2"}, {"folderId": "3"}],
    selectedFolderIds: ko.observableArray(),
};

vm.folderIndex = {};
ko.utils.arrayForEach(vm.folders, function (folder) {
    vm.folderIndex[folder.folderId] = folder;
});

/* monitors selections and publishes to the shell */
this.selectedFolders = ko.computed(function () {
    return ko.utils.arrayMap(vm.selectedFolderIds(), function (id) {
        return vm.folderIndex[id];
    });
}).publishOn("SELECTED_FOLDERS");

ko.applyBindings(vm);

1 个答案:

答案 0 :(得分:0)

ko.utils.array...助手不会自动展开可观察对象(请参阅source on github)。因此,您需要将已经解开的数组传递给它们,而不是直接传递observableArray

因此错误发生在arrayForEach来电中,正确用法是:

ko.utils.arrayForEach(viewModel.documents(), function(doc) {
   viewModel.documentIndex[doc.documentId] = doc; 
});

请注意()末尾的viewModel.documents(),以及viewModel.selectedDocumentIds()ko.utils.arrayMap的正确使用方式。

您的固定JSFiddle