How to pass value from one view model to another viewmodel in knockout js?

前端 未结 3 954
不思量自难忘°
不思量自难忘° 2021-01-22 00:51

i have two view models and i want to pass value from one view model to another viewmodel. i have two viewmodels and two div i want to display another div on click of button whic

相关标签:
3条回答
  • 2021-01-22 01:09

    You can make use of KO.postbox by the great @RyanNiemeyer

    I introduced one variable in both the viewmodels each

    In viewmodel 1 which will publish (shout) the changes once made :

    self.isVisible = ko.observable(false).publishOn("showDiv");
    

    in viewmodel 2 which will be listning to changes from viewmodel 1

    self.isVisible = ko.observable(false).subscribeTo("showDiv");
    

    Then I created one click method in first viewModel to toggle Show Div action (visible : true / false)

    self.showDiv = function(){
         if(self.isVisible())
             self.isVisible(false);
        else
            self.isVisible(true);
    }
    

    Changed visible binding from your existing markup to this :

    <div id="container2" data-bind="visible:isVisible">
    

    It now publish changes made in first viewmodel to second viewmodel. This is called pub-sub mechanism. Read more on : https://github.com/rniemeyer/knockout-postbox

    Fiddle here : http://jsfiddle.net/rahulrulez/0454h205/1/

    0 讨论(0)
  • 2021-01-22 01:24

    rjdmello already pointed you to AmplifyJS. Amplify offers (amongst other things) a publish/subscribe mechanism. Pub/sub is a good way to facilitate communication between modules that are loosely coupled. One module subscribes to a topic, and any other module can publish a message with that topic (and any data you'd like to send along). Once a topic is published, all subscribers will be notified.

    Some code demonstrating Amplify in this case:

    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);
    }
    

    Using pub/sub to keep modules loosely coupled is generally very good practise (although you shouldn't overdo it because it will become harder to track how modules cooperate).

    And while we are on the practise of good practise, don't use self = this, use Function.prototype.bind instead. http://www.smashingmagazine.com/2014/01/23/understanding-javascript-function-prototype-bind/

    0 讨论(0)
  • 2021-01-22 01:24

    For this you can follow these

    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))
        }
    }
    

    View

    <div data-bind="with:vm1">
    .
    .
    .
    </div>
    <div data-bind="with:vm2">
    .
    .
    .
    </div>  
    

    This way when you bind myfunction to click binding parent model will have the data you want to pass then on the other view model you can access parent property pageParameters.

    For more details see my post.

    0 讨论(0)
提交回复
热议问题