I'm sure I'm missing something entirely obvious here, but I'm trying out ES6 for the first time, and after five days of getting nowhere, I figured I'd open this up the community.
I have a view model class:
class TestViewModel
{
constructor(params)
{
this.firstName = ko.observable(params.firstName);
this.message = ko.computed(function() { return 'Hello, ' + this.firstName() + '!' }, this);
}
}
export default { viewModel: TestViewModel, template: templateMarkup };
(Ignore the template, it's just a paragraph tag using an import)
Then there's an entry point:
"use strict";
import $ from 'jquery';
import ko from 'knockout';
import comp from '../test-model/test-model';
ko.components.register("test-model", {
viewModel: comp.viewModel,
template: comp.template
});
let m = new comp.viewModel({ firstName: "world" });
$("document").ready(function() {
ko.applyBindings(m);
});
My page has a simple component:
<test-component></test-component>
When I view the page, the element contains my component's template. Instead of display the message "Hello, world!", the page displays "Hello, undefined!". I've debugged the process multiple times, and it always successfully creates an instance of TestViewModel with the proper parameters. But the view model that gets bound to the page is generated after that by the createViewModel function in Knockout. What am I missing in my set up to bind my instance of the model to the component?
You're mixing up components and the root view model. Your constructor will be called twice:
newit yourself on thelet m...line;Instead you need something like this:
This seems to work, but I still recommend being careful with this. The
ko.components'viewModelentry is called as a constructor function, and I personally don't know the subtle differences between a constructor function and a ES6 class. Based on the docs you could play it safe and use a custom view model factory instead: