barteloma
barteloma

Reputation: 6875

knockout js multiple viev model binding

Muiltiple view model binding application is applied here a jsfiddle application.

    ko.bindingHandlers.stopBinding = {
        init: function() {
             return { controlsDescendantBindings: true };
        }        
    };

    var shellModel = {
        selectedSection: ko.observable(),
    };

Main view separeated with sub views. When you click the "profile" button, profile sub viewmodel is activating as a selectedview. I want to put a close button in sub model and when I click it, the main selectedview object will be null.

Upvotes: 0

Views: 108

Answers (1)

Robert Slaney
Robert Slaney

Reputation: 3722

Two ways to solve this

Coupling Shell and subviews

To each sub view add a close function to calls back into the shellModel

var profileModel = {
    first: ko.observable("Bob"),
    last: ko.observable("Smith"),
    onClose: function() {
        shellModel.selectedSection(null);
    }
};

Then add some sort of close button to each subview div

<button data-bind="click: onClose">Close</button>

Decoupled using messenging

Use a sub/pub messaging library ( like Amplify or PubSubJS ). I have used amplify below.

Using a sub/pub approach will allow you to create a publishMsg binding

// Very simplistic handler.
ko.bindingHandlers.publishMsg = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext ) {
        var msgToPublish = valueAccessor();
        ko.bindingHandlers["click"].init(element, function() {
            return function() {
                amplify.publish(msgToPublish);
            }
        }, allBindings, viewModel, bindingContext);
    }        
};

Add a single button to each subview div, or 1 in the parent div

<button data-bind="publishMsg: 'subview-close'">Close</button>

Add a subscription to clear selectedSection.

// Callback for subscription
amplify.subscribe('subview-close', function() {
    shellModel.selectedSection(null);
}

You could also add an onClose function ( like in coupled solution ) but just call publish...

var profileModel = {
    ...
    onClose: function() {
        amplify.publish('subview-close');
    }
};    

But this pollutes the object models IMHO ( but gets the job done )

Upvotes: 1

Related Questions