javascript - Knockout.js - 组件之间的 Pub/Sub,双向对话

标签 javascript knockout.js

我的 Knockout 应用程序由代表表单不同部分的不同组件组成 - 所以我有一个“语言”组件、一个“国家”组件、一个“标签”组件等等。在每个组件中,我都有一个可观察数组,每当这些可观察值发生变化时,我都会通过 ko.postbox.notifySubscribers 订阅并发送通知。在另一个称为过滤器的组件中,它充当用户在表单中选择的所有过滤器的收集器,我通过 ko.postbox.subscribe 接收这些可观察值的更改。

我的问题是:如果我想在过滤器组件中进行更改并让它们也反射(reflect)在其他组件中怎么办?也就是说,如何将这种单向对话转变为双向对话?

例如,在语言组件中,我有一个下拉菜单,用户可以选择语言。在过滤器菜单中,我有包含所选语言(复选框)的列表,我希望用户能够从此处取消选择项目,同时仍然更新主组件中的下拉列表。

发布语言组件和过滤器组件的代码, 谢谢

Languages.js

ko.components.register("languages",{ 
 viewModel: function(){
  var self            = this;
  self.languages      = ko.observableArray();
  self.selectedLangs  = ko.observableArray();

  xhr.languages()
   .done(function (langs) {
     self.languages(langs);
  }); 

  self.selectedLangs.subscribe(function(values) {
    ko.postbox.notifySubscribers(
     _.map(values,function(val){
      var obj = _.findWhere(self.languages(), {id: val});
      return obj.text;
    }), "selectedLangs");
  });
},
template: 
'<fieldset id="language" class="wfp-u-1">\
  <div class="wfp-grid">\
    <label for="dss-language" class="wfp-u-1 wfp-u-lg-1-4">\
      Language <span class="loader"><i class="icon-loader"></i></span>\
      <em>Multiselection available</em>\
    </label>\
    <select id="dss-language" name="language" multiple="" class="wfp-u-1 wfp-u-lg-3-4 ui dropdown search selection"\
      data-bind="\
        options: languages,\
        optionsText: \'text\',\
        optionsValue: \'id\',\
        optionsCaption: \'Select one or more languages\',\
        selectedOptions: selectedLangs\">\
    </select>\
  </div>\
</fieldset>'
});

Filters.js

ko.components.register("filters",{ 
 viewModel: function(){

var self = this;
self.selectedLangs      = ko.observableArray();

ko.postbox.subscribe(function(langs) {     
  self.selectedLangs(langs);
}, self, "selectedLangs");
},
template: 
'<ul class="wfpList wfpFieldList mCustomScrollbar">\
  <li>\
    <a data-target="language">Language</a><i class="ico-angle-down"></i>\
    <!-- ko foreach: selectedLangs -->\
      <span data-bind="text: $data"></span>\
    <!-- /ko -->\
  </li>\
</ul>'
});

最佳答案

复制 John Papa 的答案 ( https://stackoverflow.com/a/10818849/1287183 ):

An option is to create an isolated datacontext that maintains the models of observables. the viewmodels all look to the datacontext for their data and refer to the same objects, so when one updates, they all do. The VM's dependency is on the datacontext but not on other VMs. I've been doing this lately and it has worked well.

关于javascript - Knockout.js - 组件之间的 Pub/Sub,双向对话,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38984924/

相关文章:

javascript - knockout 和 MVC 2.0

javascript - 将 Request 2.0 应用程序生成的请求发送到 "/me"之外的其他位置

javascript - 如果 Knockout pureCompulated 包含可能并不总是存在的可观察值,它可以工作吗?

javascript - 使用内置 `crypto` 在 nodejs 中进行密码散列

javascript - 动态附加google plus按钮的回调参数

javascript - 单击单选按钮时,元素内容更改为图像

javascript - 如何绑定(bind)knockout viewmodel动态加载页面?

javascript - knockout 选项条件 css

javascript - 链接上的 mailto 协议(protocol)以 HTML 标签打开

javascript - 将 decodeURI 与 cookie javascript 一起使用