【问题标题】:Knockout Component Not Binding View Model (ES6)淘汰赛组件不绑定视图模型(ES6)
【发布时间】:2016-01-19 05:32:19
【问题描述】:

我确定我在这里遗漏了一些非常明显的东西,但我是第一次尝试 ES6,在五天无果之后,我想我应该在社区中打开它。

我有一个视图模型类:

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

(忽略模板,它只是一个使用导入的段落标签)

然后有一个入口点:

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

我的页面有一个简单的组件:

<test-component></test-component>

当我查看页面时,该元素包含我的组件的模板。页面不显示消息“Hello, world!”,而是显示“Hello, undefined!”。我已经多次调试了这个过程,它总是成功地创建了一个具有正确参数的 TestViewModel 实例。但是绑定到页面的视图模型是由 Knockout 中的 createViewModel 函数生成的。我在将模型实例绑定到组件的设置中缺少什么?

【问题讨论】:

    标签: knockout.js ecmascript-6 knockout-components


    【解决方案1】:

    您正在混淆组件和根视图模型。您的构造函数将被调用两次:

    1. 曾经是因为您自己在let m... 行上new 它;
    2. 曾经因为你的视图实例化了组件,告诉KO创建你的viewModel的实例;

    相反,你需要这样的东西:

    "use strict";
    
    class TestViewModel
    {
      constructor(params)
      {
        this.firstName = ko.observable(params.firstName);
        this.message = ko.computed(() => 'Hello, ' + this.firstName() + '!');
      }
    }
    
    var templateMarkup = "<p data-bind='text: message'></p>";
    var comp = { viewModel: TestViewModel, template: templateMarkup };
    
    ko.components.register("test-component", {
      viewModel: comp.viewModel,
      template: comp.template
    });
    
    $("document").ready(function() {
      ko.applyBindings({});
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <test-component params="firstName: 'world'"></test-component>

    这个seems to work,但我仍然建议小心这个。 ko.components'viewModel入口被称为构造函数,我个人不知道构造函数和ES6类之间的细微差别。基于the docs,您可以放心使用自定义视图模型工厂:

    ko.components.register("test-component", {
      viewModel: { createViewModel: (params, componentInfo) => new comp.viewModel(params) },
      template: comp.template
    });
    

    【讨论】:

    • 感谢您的示例和解释。这现在更有意义了。至于 ES6 的类,我是用 Babel 把它们转成 ES5 的,所以它们就变成了函数。
    • 啊,我不知道你使用了 Babel,但是从复选标记中我收集到我提出的解决方案无论如何都可以解决问题 :-)。编码愉快!
    猜你喜欢
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多