knockout component registration does not execute viewModel and could not append template

952 Views Asked by At

For a simple test.html, knockout component works fine in my simple test.html, I mean it executes the view model and appends template successfully but doesn't work in a huge index.html. Anyone have an idea?

file test.html:

  <html>   
    <body> 
    <div id="mandiv" class data-bind="component: 'user' "> </div>
    <script type='text/javascript' src='./js/knockout-3.4.0.js'></script>
    <script type="text/javascript" src="app.js"></script> 
  </body>  
  </html>

file app.js:

var userModel = function() {
         console.log("I inside model");
        firstname = ko.observable("aaa");
        lastname = ko.observable("bb");
        console.log("firstname: " + firstname());
        console.log("test");
        this.fullname = ko.pureComputed(function(){

            return firstname() + " "  + lastname();   
        }); 

};

console.log("I out here");

ko.components.register('user', {
    viewModel: userModel,
    template : '<p> <input type="text" placeholder="first name" data-bind="value:firstname"> </p> ' +    ' <p> <input type="text" placeholder="last name" data-bind="value:lastname"> </p>' + '<p> full name :  <span data-bind="text: fullname"> </span> </p> </div>'


});

ko.applyBindings();

It works fine on test.html.
In a huger index.html, I did the same thing. But it does not work. It did not execute the viewModel and could not append the template. Due to my index.html is too long, I just copy the related code.

index.html related code:

 <div id="mandiv" class="hidden" data-bind="component: 'user' "> 
 </div> 

Before this div and after this div are separate divs. And include knockout.js and app.js before any js file. It does not work. Any ideas? Appreciated!

1

There are 1 best solutions below

4
Nimesco On

For one, I would start using var self = this; then append all properties to self in your viewModel.

userModel = function() {
    var self = this;

    self.firstname = ko.observable("aaa");
    self.lastname = ko.observable("bb");
    self.fullname = ko.pureComputed(function(){
        return self.firstname() + " "  + self.lastname();   
    });

    return self;
}; 

second, create a new instance of the viewModel instead of using the same instance multiple times?

ko.components.register('user', {
  viewModel: {
    createViewModel: function(params, componentInfo) { 
      return new userModel();
    }
  },
  template : '<p> <input type="text" placeholder="first name" data-bind="value:firstname"> </p> ' +    ' <p> <input type="text" placeholder="last name" data-bind="value:lastname"> </p>' + '<p> full name :  <span data-bind="text: fullname"> </span> </p> </div>'
});