为Component设置viewModel = $ data

时间:2015-04-09 19:10:53

标签: knockout.js

我刚刚开始了解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。

这是正确的方式还是我错过了什么?

2 个答案:

答案 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