我刚刚开始了解Knockout Components。现在我正试图创建一个"仅模板"零件。我遇到的问题是将组件的viewmodel设置为我使用Component的$ data。我已经从Knockout页面(http://knockoutjs.com/documentation/component-overview.html)
修改了示例这是一个显示我已做过的事情:http://plnkr.co/edit/23PVEW9aQ63A9yq2wRJp
我在foreach中使用该组件,如:
<ul data-bind="foreach: products">
<li class="product">
<strong data-bind="text: name"></strong>
<div data-bind="component: { name: 'like-widget', params: {data: $data}}"></div>
</li>
</ul>
这是组件:
ko.components.register('like-widget', {
viewModel: function(params) {
// Data: value is either null, 'like', or 'dislike'
this.data = params.data;
// Behaviors
this.like = function() {
this.data.userRating('like');
}.bind(this);
this.dislike = function() {
this.data.userRating('dislike');
}.bind(this);
},
template: '<div data-bind="with: data"><div class="like-or-dislike" data-bind="visible: !userRating()">\
<button data-bind="click: $parent.like">Like it</button>\
<button data-bind="click: $parent.dislike">Dislike it</button>\
</div>\
<div class="result" data-bind="visible: userRating">\
You <strong data-bind="text: userRating"></strong> it\
</div></div>'
});
这样做是有效的,但似乎有一种更简单的方法可以将组件的viewModel设置为$ data。
这是正确的方式还是我错过了什么?
答案 0 :(得分:0)
您可以在Product类中定义喜欢和不喜欢的函数并使用模板绑定,这样您就可以将整个Product对象绑定到模板。
我已经分叉你的插图来展示我是如何做到的
http://plnkr.co/edit/fYaBw1Yjsivg6O8x3JgB
<div data-bind="template: { name: 'like-template', data: $data}"></div>
模板看起来像这样
<script type="text/html" id="like-template">
<div class="like-or-dislike" data-bind="visible: !userRating()">
<button data-bind="click:like">Like it</button>
<button data-bind="click:dislike">Dislike it</button>
</div>
<div class="result" data-bind="visible: userRating">
You <strong data-bind="text: userRating"></strong> it
</div></div>
</script>
答案 1 :(得分:0)
虽然您可以将$ data作为参数传递,但请注意,您现在已将组件的设计与视图模型的设计紧密耦合。更可重用的方法是将name和userRating作为参数传递,并使用它们为组件构建视图模型,该模型对产品视图模型的结构一无所知。
话虽如此,您不需要将$ data作为参数传递给组件,以便能够访问它。相反,您可以在组件绑定的元素上使用ko.contextFor,并以这种方式获取$ data。
示例:
ko.components.register('like-widget', {
viewModel: {
createViewModel: function (params, componentInfo) {
var context = ko.contextFor(componentInfo.element);
var self = context.$data;
return ko.utils.extend(context.$data, {
ratingButtonVisible: ko.computed(function() {
return (self.userRating()==null);
}),
ratingDescriptionVisible: ko.computed(function() {
return !(self.userRating()==null);
}),
like: function() {
self.userRating('like');
},
dislike: function() {
self.userRating('dislike');
}
});
}
},
template: { element: 'like-template' }
});
ko.applyBindings(new MyViewModel());
工作JSFiddle