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 函数之后生成的。我在将模型实例绑定到组件的设置中缺少什么?
您混淆了组件和根视图模型。您的构造函数将被调用两次:
- 一次是因为你
new
自己上let m...
行;
- 有一次因为你的视图实例化组件,告诉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
});
我确定我在这里遗漏了一些非常明显的东西,但我是第一次尝试 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 函数之后生成的。我在将模型实例绑定到组件的设置中缺少什么?
您混淆了组件和根视图模型。您的构造函数将被调用两次:
- 一次是因为你
new
自己上let m...
行; - 有一次因为你的视图实例化组件,告诉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
});