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

Knockout Component Not Binding View Model (ES6)

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

我有一个视图模型class:

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 函数之后生成的。我在将模型实例绑定到组件的设置中缺少什么?

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

  1. 一次是因为你new自己上let m...行;
  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, but I still recommend being careful with this. The ko.components' viewModel entry is called as a constructor function, and I personally don't know the subtle differences between a constructor function and a ES6 class. Based on the docs 您可以放心使用自定义视图模型工厂:

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