Knockout组件不绑定视图模型(ES6)

时间:2016-01-19 05:32:20

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

我确信我错过了一些完全明显的东西,但是我第一次尝试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,undefined!”,而不是显示消息“Hello,world!”。我已多次调试该进程,并且它总是使用适当的参数成功创建TestViewModel的实例。但是之后由Knockout中的createViewModel函数生成绑定到页面的视图模型。我在设置中将模型实例绑定到组件时缺少什么?

1 个答案:

答案 0 :(得分:1)

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

  1. 一次,因为您newlet m...自己{/ 1}}
  2. 一次因为您的视图实例化组件,告诉KO创建viewModel的实例;
  3. 相反,你需要这样的东西:

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