foreach 中的自定义元素在淘汰赛中没有预期的模型
Custom element inside foreach have not expected model in knockout
淘汰赛的新手我正在尝试为自定义元素建立 POC。
模型很简单,一个 MainModel 包含一个 LinkModel 数组。
目标是遍历链接数组以显示每个 LinkModel 对象的 1 个自定义元素 "settings-view-link"。
function LinkModel(params) {
var self = this;
self.name = ko.observable(params.name);
}
function MainModel() {
var self = this;
self.links = ko.observableArray([
new LinkModel({ name: "link1"}),
new LinkModel({ name: "link2"})
]);
};
$(function () {
//registration of the custom element
ko.components.register('settings-view-link',
{
viewModel: LinkModel,
template: "<div><strong data-bind='text: name'></strong></div>"
});
ko.applyBindings(new MainModel());
});
<div>
<ul data-bind="foreach: links">
<p data-bind="text: name"></p> <!-- handled correctly -->
<settings-view-link></settings-view-link> <!-- handled not the way I expect-->
</ul>
</div>
我看到的是,如果在自定义元素中我需要使用 $parent。让我的数据绑定按预期工作。使用
<div><strong data-bind='text: $parent.name'></strong></div>
而不是
<div><strong data-bind='text: name'></strong></div>
使我的链接名称出现在网页上。
我期望在自定义元素内部它处理一个 LinkModel 对象,但它不是,它在某种程度上是一个 "submodel"。
有人可以解释为什么我必须使用 $parent 吗?代码是错误的,但为什么?我真的希望在我的自定义元素中有一个 LinkModel 对象。
非常感谢
因为您的自定义组件指定了一个 viewModel
选项,所以 knockout 将为您创建该视图模型的一个新实例。您可以省略 属性,knockout 会将组件绑定到提供的参数:
Components usually have viewmodels, but they don’t necessarily have to. A component can specify just a template. In this case, the object to which the component’s view is bound is the params object that you passed to the component binding
来源:http://knockoutjs.com/documentation/component-binding.html#note-template-only-components
这个例子可能更好地解释了我的意思。第一个组件指定一个视图模型函数,该函数被实例化并绑定到组件实例。
第二个组件将$data
作为参数传递,基本上用作模板。如果您不想自动创建新的视图模型,您可能只需要模板绑定。
var instanceCounter = 0;
var ViewModel = function() {
this.nr = instanceCounter++;
}
ko.components.register('testComponent1', {
viewModel: ViewModel,
template: '<div data-bind="text: nr"></div>'
});
ko.components.register('testComponent2', {
template: '<div data-bind="text: nr"></div>'
});
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<section>
<h2>New instance for each component</h2>
<div data-bind='component: {
name: "testComponent1"
}'></div>
<div data-bind='component: {
name: "testComponent1"
}'></div>
<div data-bind='component: {
name: "testComponent1"
}'></div>
</section>
<section>
<h2>Same instance for each component</h2>
<div data-bind='component: {
name: "testComponent2",
params: $data
}'></div>
<div data-bind='component: {
name: "testComponent2",
params: $data
}'></div>
<div data-bind='component: {
name: "testComponent2",
params: $data
}'></div>
</section>
淘汰赛的新手我正在尝试为自定义元素建立 POC。
模型很简单,一个 MainModel 包含一个 LinkModel 数组。
目标是遍历链接数组以显示每个 LinkModel 对象的 1 个自定义元素 "settings-view-link"。
function LinkModel(params) {
var self = this;
self.name = ko.observable(params.name);
}
function MainModel() {
var self = this;
self.links = ko.observableArray([
new LinkModel({ name: "link1"}),
new LinkModel({ name: "link2"})
]);
};
$(function () {
//registration of the custom element
ko.components.register('settings-view-link',
{
viewModel: LinkModel,
template: "<div><strong data-bind='text: name'></strong></div>"
});
ko.applyBindings(new MainModel());
});
<div>
<ul data-bind="foreach: links">
<p data-bind="text: name"></p> <!-- handled correctly -->
<settings-view-link></settings-view-link> <!-- handled not the way I expect-->
</ul>
</div>
我看到的是,如果在自定义元素中我需要使用 $parent。让我的数据绑定按预期工作。使用
<div><strong data-bind='text: $parent.name'></strong></div>
而不是
<div><strong data-bind='text: name'></strong></div>
使我的链接名称出现在网页上。
我期望在自定义元素内部它处理一个 LinkModel 对象,但它不是,它在某种程度上是一个 "submodel"。 有人可以解释为什么我必须使用 $parent 吗?代码是错误的,但为什么?我真的希望在我的自定义元素中有一个 LinkModel 对象。
非常感谢
因为您的自定义组件指定了一个 viewModel
选项,所以 knockout 将为您创建该视图模型的一个新实例。您可以省略 属性,knockout 会将组件绑定到提供的参数:
Components usually have viewmodels, but they don’t necessarily have to. A component can specify just a template. In this case, the object to which the component’s view is bound is the params object that you passed to the component binding
来源:http://knockoutjs.com/documentation/component-binding.html#note-template-only-components
这个例子可能更好地解释了我的意思。第一个组件指定一个视图模型函数,该函数被实例化并绑定到组件实例。
第二个组件将$data
作为参数传递,基本上用作模板。如果您不想自动创建新的视图模型,您可能只需要模板绑定。
var instanceCounter = 0;
var ViewModel = function() {
this.nr = instanceCounter++;
}
ko.components.register('testComponent1', {
viewModel: ViewModel,
template: '<div data-bind="text: nr"></div>'
});
ko.components.register('testComponent2', {
template: '<div data-bind="text: nr"></div>'
});
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<section>
<h2>New instance for each component</h2>
<div data-bind='component: {
name: "testComponent1"
}'></div>
<div data-bind='component: {
name: "testComponent1"
}'></div>
<div data-bind='component: {
name: "testComponent1"
}'></div>
</section>
<section>
<h2>Same instance for each component</h2>
<div data-bind='component: {
name: "testComponent2",
params: $data
}'></div>
<div data-bind='component: {
name: "testComponent2",
params: $data
}'></div>
<div data-bind='component: {
name: "testComponent2",
params: $data
}'></div>
</section>