我的 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/