knockout.jsknockout-componentssystemjs

Knockout Components - Custom Component Loaders


I'm using Knockout Components and with System.js for module loading.

I have a custom component loader:

var myComponentLoader = {
  loadComponent: function(name, componentConfig, callback) {
    System.import(componentConfig.myLoader)
    .then(function(loadedComponent) {

      var result = {
        template: ko.utils.parseHtmlFragment(loadedComponent.componentTemplate),
        createViewModel: loadedComponent.MyComponentViewModel
      }
      callback(result);
    })
    // .catch(function(myError){
    //   alert(myError);
    //   callback(null);
    // });
    }
};

// Register it
ko.components.loaders.unshift(myComponentLoader);

ko.components.register('my-component', { myLoader: './app/components/components' });

But this fails with the following message:

TypeError: undefined is not a function {stack: (...), message: "undefined is not a function"}

This is how my result.template looks like:

<div>This is my component template</div>
<div data-bind="text: myName"></div>

This is how my result.createViewModel looks like:

 function MyComponentViewModel(params) {
        // Set up properties, etc.
        this.myName = ko.observable("Amy Smith");
        this.doSomething(params);
        this.boundAt = ko.observable(moment().format());
    }

Here is the full error:

Potentially unhandled rejection [1] TypeError: undefined is not a function
    at Object.ko.utils.cloneNodes (http://localhost:8081/lib/bower/knockout@3.3.0/dist/knockout.js:270:48)
    at cloneTemplateIntoElement (http://localhost:8081/lib/bower/knockout@3.3.0/dist/knockout.js:3644:41)
    at null.callback (http://localhost:8081/lib/bower/knockout@3.3.0/dist/knockout.js:3621:21)
    at Function.ko_subscribable_fn.notifySubscribers (http://localhost:8081/lib/bower/knockout@3.3.0/dist/knockout.js:1103:38)
    at http://localhost:8081/lib/bower/knockout@3.3.0/dist/knockout.js:3151:54
    at http://localhost:8081/lib/bower/knockout@3.3.0/dist/knockout.js:3169:21
    at http://localhost:8081/lib/bower/knockout@3.3.0/dist/knockout.js:3198:29
    at eval (http://localhost:8081/app/components/components-bootstrapper.js!eval:32:13)
    at O (http://localhost:8081/lib/es6-module-loader.js:7:7439)
    at K (http://localhost:8081/lib/es6-module-loader.js:7:7071)

Solution

  • To provide your custom configuration handling logic you need to implement the loadComponent method as described in the documentation.

    However you need to watch out what you return from it, because according to the documentation: