Search code examples
knockout.jsrequirejsknockout-components

Knockout.js: Local Observables within Component ViewModel


I'm using knockout's components (loaded via require.js) to create a login widget.

Javascript:

ko.components.register('login-widget', {
    viewModel: { require: '/components/login-widget.js' },
    template: { require: 'text!/components/login-widget.html' }
});

function MyViewModel() {
    var self = this;
    self.email = ko.observable();
    self.password = ko.observable();
    self.mode = ko.observable('login');
}

ko.applyBindings(new MyViewModel());

html

<div class="container-fluid">
    <h1>Hello world</h1>
    <login-widget params="{ email: email, password: password, mode: mode}"></login-widget>
</div>

Component Javascript

define(['knockout'], function (ko) {
    function LoginWidgetViewModel(params) {
        var self = this;

        self.email = params.email;
        self.password = params.password;

        self.mode = params.mode;
    }
    return LoginWidgetViewModel;
});

Component html snippet:

 <input type="email" class="form-control" placeholder="email" data-bind="value:email">

This all works fine, but when I try to move the observable into to the LoginWidgetViewModel instead of passing them as parameters, they don't bind correctly to the model. So when I use

define(['knockout'], function (ko) {
    function LoginWidgetViewModel(params) {
        var self = this;

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

        self.mode = ko.observable('login');
    }
    return LoginWidgetViewModel;
});

instead of:

Working Login

I get:

Not working login

Any suggestions?


Solution

  • I was loading knockout and require.js globally, and then loading the viewmodels in using require, which was loading another instance of knockout. I removed the non-require reference to knockout and everything started working how I'd expect it to work.

    Found solution over at Issue loading knockout components view model using requireJS