【问题标题】:Observable arrays with knockout publishing/subscribing具有淘汰发布/订阅的可观察数组
【发布时间】:2013-04-24 19:42:51
【问题描述】:

我正在关注这篇文章:

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

允许我的一个虚拟机与另一个虚拟机通信。我的一个 viewModel 有一个数组,我需要将其公开给另一个 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);

【问题讨论】:

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


    【解决方案1】:

    ko.utils.array... 助手不会自动解开 observables(参见 source on github)。因此,您需要将已经解包的数组传递给它们,而不是直接传递 observableArray

    所以错误出现在您的arrayForEach 调用中,正确用法是:

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

    注意viewModel.documents()末尾的(),以及您如何正确使用ko.utils.arrayMap中的viewModel.selectedDocumentIds()

    您的固定JSFiddle

    【讨论】:

    • 谢谢。我在我的项目中尝试了这个,但它不起作用,我无法在 jsFiddle 上重现该问题。在我的项目中,“文件夹”是一个可观察的视图模型数组,每个视图模型都有一个属性 folderId。这些是由 ko 映射插件制作的。知道还会发生什么吗?
    • 您是否设法找出实际代码中的问题?
    • 正要回帖。我只需要将属性引用为未包装的 observables - folder.id() 而不是 folder.id。非常感谢:)
    猜你喜欢
    • 2011-09-17
    • 1970-01-01
    • 2012-09-08
    • 2015-08-29
    • 2015-10-05
    • 2019-03-27
    • 2013-05-30
    • 1970-01-01
    相关资源
    最近更新 更多