我有两个视图模型,我想将值从一个视图模型传递到另一个视图模型。我有两个viewmodels和两个div我想在div 1中点击按钮显示另一个div。
这里是html代码
<div id="container1">
<ul >
<li >Container1 item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
<button data-bind="click:showDiv">show another div</button>
</div>
<div id="container2" data-bind="visible:show">
<ul>
<li >Container2 item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
</div>
这是脚本
function Container1ViewModel()
{
var self = this;
self.myItems = ko.observableArray();
self.myItems.push("ABC");
self.myItems.push("CDE");
}
function Container2ViewModel() {
var self = this;
self.myItems = ko.observableArray();
self.myItems.push("XYZ");
self.myItems.push("PQR");
}
var container1VM;
var container2VM;
$(document).ready(function() {
if ($.isEmptyObject(container1VM)) {
container1VM = new Container1ViewModel();
ko.applyBindings(container1VM, document.getElementById("container1"));
}
if ($.isEmptyObject(container2VM)) {
container2VM = new Container2ViewModel();
ko.applyBindings(container2VM, document.getElementById("container2"));
}
});
我该怎么办?
答案 0 :(得分:5)
你可以使用伟大的@RyanNiemeyer
来使用KO.postbox我在每个视图模型中引入了一个变量
在viewmodel 1中,它将发布(喊出)一旦做出的更改:
self.isVisible = ko.observable(false).publishOn("showDiv");
在viewmodel 2中,它将列出来自viewmodel 1的更改
self.isVisible = ko.observable(false).subscribeTo("showDiv");
然后我在第一个viewModel中创建了一个单击方法来切换Show Div动作(可见:true / false)
self.showDiv = function(){
if(self.isVisible())
self.isVisible(false);
else
self.isVisible(true);
}
将现有标记的可见绑定更改为:
<div id="container2" data-bind="visible:isVisible">
它现在将第一个viewmodel中所做的更改发布到第二个viewmodel。这称为pub-sub机制。阅读更多信息:https://github.com/rniemeyer/knockout-postbox
答案 1 :(得分:0)
rjdmello已经向您指出了AmplifyJS。 Amplify提供(除其他事项外)发布/订阅机制。发布/订阅是促进松散耦合的模块之间的通信的好方法。一个模块订阅一个主题,任何其他模块都可以发布包含该主题的消息(以及您要发送的任何数据)。发布主题后,将通知所有订阅者。
在这种情况下,一些代码演示了Amplify:
Container1ViewModel.prototype.showDiv = function (event) {
amplify.publish('show-div', { clickedButton: event.target });
}
function Container2ViewModel() {
var onShowDiv = function (data) {
if ($(data.clickedButton).hasClass('.enabled')) {
// Show me teh div!!
this.myItems.push("ABC");
}
};
this.myItems = ko.observableArray();
this.myItems.push("XYZ");
this.myItems.push("PQR");
amplify.subscribe('show-div', this, onShowDiv, 1);
}
使用pub / sub来保持模块松散耦合通常是非常好的做法(尽管你不应该过度使用它,因为跟踪模块如何合作将变得更加困难)。
虽然我们正在练习良好做法,但请不要使用self = this
,而是使用Function.prototype.bind
。
http://www.smashingmagazine.com/2014/01/23/understanding-javascript-function-prototype-bind/
答案 2 :(得分:0)
为此你可以按照这些
的ViewModels
function vm1(parent){
var self = this
self.parent = ko.observable(parent)
.
.
.
self.myfunction(data){
self.parent().pageParameters(data)
}
}
function vm2(parent){
var self = this
self.parent = ko.observable(parent)
.
.
.
self.myotherfunction(){
var othervmdata = self.parent().pageParameters()
.
.
}
}
function vm(){
var self = this
self.vm1 = ko.observable();
self.vm2 = ko.observable();
self.pageParameters = ko.observable
self.loadData = function(){
self.vm1(new vm1(this))
self.vm2(new vm1(this))
}
}
查看
<div data-bind="with:vm1">
.
.
.
</div>
<div data-bind="with:vm2">
.
.
.
</div>
这种方式将myfunction
绑定到点击绑定时,父模型将包含您要传递的数据,然后在另一个视图模型上可以访问父属性pageParameters
。
有关详细信息,请参阅my发布。