ko邮箱请求数据和ko viewmodels之间的通信

时间:2014-06-10 20:37:40

标签: knockout.js

使用库ko邮箱可以订阅主题并解耦淘汰视图模型。但是如果我想在viewmodel之间请求数据呢?例如,通过另一个viewmodel中包含的数组中的id获取项目。这可能吗?如果不是没有使用Require JS的最佳解决方案。一种可能的选择是使用主视图模型在视图模型之间进行通信。这是个好主意吗?

感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

ko.postbox确实包括"正常" pubsub API,因此可以执行请求/响应对。这是一个基本的想法,您在一个视图模型中侦听请求并发送匹配的响应。另一个视图模型启动请求并订阅响应。

var ViewModelOne = function() {
    this.items = ko.observableArray([
        { id: "1", name: "one" },
        { id: "2", name: "two" },
        { id: "3", name: "three" }
    ]);

    this.getItemById = function(id) {
        return id && ko.utils.arrayFirst(this.items(), function(item) {
            return item.id === id
        });
    };

    //listen for requests
    ko.postbox.subscribe("item.request", function(id) {
        //publish a response
        ko.postbox.publish("item.response", this.getItemById(id));
    }, this);
};

var ViewModelTwo = function() {
    this.id = ko.observable().publishOn("item.request");
    this.item = ko.observable().subscribeTo("item.response");
};

此处示例:http://jsfiddle.net/rniemeyer/x4nBr/

其他一些注释/想法:

  • 我个人不喜欢可以在任何一方修改的pub / sub对象,尽管这样做完全有效。我可能会创建一个我正在传递的对象的副本,如ko.toJS(responseData)

  • 在执行此类请求/响应时,如果涉及多个订阅者/发布者,那么您可能希望使主题变得更复杂(暂时订阅item.response.xxxx等唯一的响应主题,然后在响应回来时处理订阅)。以下是使用ID的示例,但也可以使用唯一标识符:http://jsfiddle.net/rniemeyer/2Ycs3/