【问题标题】:Knockout Components - Custom Component Loaders淘汰赛组件 - 自定义组件加载器
【发布时间】:2017-08-18 23:21:27
【问题描述】:

我正在使用 Knockout Components 和 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/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)

【问题讨论】:

  • 您看过knockoutjs.com/documentation/component-loaders.html 文章“实现自定义组件加载器”部分吗?
  • 嗨@TSV 我能够创建如上所述的自定义组件加载器,这就是我使用的文档。我的问题是我想使用的语法适用于 RequireJS,但我需要让它适用于 SystemJS。谢谢
  • 你需要实现loadComponent方法(knockoutjs.com/documentation/…)。在那里你可以用componentConfig 做任何事情,你可以在那里添加你的自定义配置解析逻辑。如果您发布当前的自定义加载器代码,会更容易为您提供帮助。
  • 嗨@nemesv,我已经尝试了你的建议。我更近了!我还根据您的要求使用我正在使用的代码更新了问题。谢谢
  • 模板属性必须包含一个 DOM 节点数组:所以试试template: ko.utils.parseHtmlFragment(loadedComponent.componentTemplate)

标签: knockout.js knockout-components systemjs


【解决方案1】:

要提供自定义配置处理逻辑,您需要实现loadComponent 方法,如documentation 中所述。

但是,您需要注意从中返回的内容,因为根据文档:

  • template 属性必须包含一个 DOM 节点数组:因此,如果您的加载器加载一个字符串,您需要先解析它:

    template: ko.utils.parseHtmlFragment(loadedComponent.componentTemplate)
    
  • createViewModel 必须包含 工厂函数,因此不能直接包含您的视图模型构造函数。所以你需要用

    包装它
    createViewModel: function (params, componentInfo) { return new loadedComponent.viewModel(params, componentInfo); } 
    

【讨论】:

猜你喜欢
  • 2020-12-18
  • 2015-12-21
  • 2014-11-08
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 2017-11-29
  • 1970-01-01
相关资源
最近更新 更多