Sam
Sam

Reputation: 1343

Share variable state between ViewModels in Knockoutjs

I created an application with a topbar (HeaderViewModel) and a link on it that opens a modal with a login form (LoginViewModel).

The LoginViewModel assigned to the modal handles the login functionality:

var LoginViewModel = function () {
    var self = this;

    self.email = ko.observable();
    self.password = ko.observable();

    self.loggedIn = ko.observable(false);

    self.login = function () {
        // loggedIn true if ajax succeeded
    }
    ...
}

After the login (ajax call) has succeeded the modal closes and the HeaderViewModel should be aware of the loggedIn state so the knockout if/else statement can handle the visibilities according the the users role.

#header (only attached to HeaderViewModel):

<!-- ko if: loggedIn --> //loggedIn not known in HeaderViewModel
    <p>Visible for logged in users</p>
<!-- /ko -->

app.js:

$(function () {
    ko.applyBindings(new HeaderViewModel, $("#header")[0]);
    ko.applyBindings(new LoginViewModel, $("#login")[0]);
});

How can I make this work?

Upvotes: 2

Views: 234

Answers (1)

Jeroen
Jeroen

Reputation: 63840

There are two different approaches.

1. Root view model

Don't call ko.applyBindings twice. Instead, create one Root view model that composes the other two.

function RootViewModel() {
    this.headerViewModel = new HeaderViewModel();
    this.loginViewModel = new LoginViewModel();
}

ko.applyBindings(new RootViewModel());
<body>
  <div data-bind="with: headerViewModel">
  </div>
  <div data-bind="with: loginViewModel">
    login dialog code here
  </div>
  etc.
</body>

You can then choose any javascript method of your liking to make sure the login feature will share its knowledge, including:

  • Calling $root.login in the login div and placing login code there;
  • newing the LoginViewModel with a parameter: a callback to notify the $root and possibly other sub view models (like the Header) of changed current user credentials;

2. Pub-sub

Use some kind of pub-sub mechanism. Options include:

The LoginViewModel will publish login results, and any subscriber can respond accordingly.

Upvotes: 2

Related Questions