2015-02-24 4 views
2

Я использую нокаут-компоненты и System.js для загрузки модуля.Компоненты нокаута - пользовательские загрузчики компонентов

У меня есть пользовательский компонент загрузчика:

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' }); 

Но это терпит неудачу со следующим сообщением:

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

Это как мой result.template выглядит следующим образом:

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

Вот как выглядит мой result.createViewModel:

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

Вот полная ошибка:

Potentially unhandled rejection [1] TypeError: undefined is not a function 
    at Object.ko.utils.cloneNodes (http://localhost:8081/lib/bower/[email protected]/dist/knockout.js:270:48) 
    at cloneTemplateIntoElement (http://localhost:8081/lib/bower/[email protected]/dist/knockout.js:3644:41) 
    at null.callback (http://localhost:8081/lib/bower/[email protected]/dist/knockout.js:3621:21) 
    at Function.ko_subscribable_fn.notifySubscribers (http://localhost:8081/lib/bower/[email protected]/dist/knockout.js:1103:38) 
    at http://localhost:8081/lib/bower/[email protected]/dist/knockout.js:3151:54 
    at http://localhost:8081/lib/bower/[email protected]/dist/knockout.js:3169:21 
    at http://localhost:8081/lib/bower/[email protected]/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) 
+0

Вы видели http://knockoutjs.com/documentation/component-loaders.html статью «Реализация загрузчика пользовательского компонента» раздел? – TSV

+0

Hi @TSV Мне удалось создать пользовательские загрузчики компонентов, как указано выше, и это была документация, которую я использовал. Моя проблема в том, что синтаксис, который я хочу использовать, работает с RequireJS, но мне нужно заставить его работать с SystemJS. Спасибо –

+0

Вам необходимо реализовать метод loadComponent (http://knockoutjs.com/documentation/component-loaders.html#functions-you-can-implement). Там вы можете сделать что-либо с помощью 'componentConfig', и вы можете добавить свою собственную логику синтаксического анализа. Было бы проще помочь вам, если вы разместите свой текущий пользовательский код загрузчика. – nemesv

ответ

3

Чтобы обеспечить пользовательскую логику обработки конфигурации необходимо реализовать метод loadComponent, как описано в documentation.

Однако вы должны смотреть, что вы вернетесь из него, потому что в соответствии с документацией:

  • Свойство template должен содержать массив DOM узлов: так что если ваш загрузчик загружает строку вам нужно разобрать его сначала:

    template: ko.utils.parseHtmlFragment(loadedComponent.componentTemplate) 
    
  • createViewModel должен содержать функцию с заводской, поэтому не напрямую ваша функция конструктора представлений. Так что вам нужно, чтобы обернуть его

    createViewModel: function (params, componentInfo) { return new loadedComponent.viewModel(params, componentInfo); } 
    
+0

Спасибо за советы. Я создал рабочий стол для загрузки systemjs: https://gist.github.com/jpolvora/3712241510e1b1023fbb00d0285dedf8 –