1

我敢肯定我在这里遗漏了一些非常明显的东西,但我是第一次尝试 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 函数生成的。我在将模型实例绑定到组件的设置中缺少什么?

4

1 回答 1

2

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

  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>

似乎有效,但我仍然建议小心这一点。'入口被称为构造函数,我个人不知道构造函数和 ES6 类之间的细微差别ko.componentsviewModel根据文档,您可以安全地使用它并改用自定义视图模型工厂:

ko.components.register("test-component", {
  viewModel: { createViewModel: (params, componentInfo) => new comp.viewModel(params) },
  template: comp.template
});
于 2016-01-19T07:49:22.983 回答