如何将值从一个视图模型传递到knockout js中的另一个视图模型?

时间:2014-08-14 11:01:05

标签: knockout.js javascript knockout-mvc

我有两个视图模型,我想将值从一个视图模型传递到另一个视图模型。我有两个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"));
    }
});

我该怎么办?

3 个答案:

答案 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

在这里摆弄:http://jsfiddle.net/rahulrulez/0454h205/1/

答案 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.bindhttp://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发布。