多个Knockout组件看到相同的属性

时间:2015-07-07 15:00:15

标签: knockout.js

更新 有趣的是,如果我将HTML嵌入到ko.component.register函数的template属性中,它就可以正常工作。

https://jsfiddle.net/h5rnqwu4/1/

ko.components.register('item-2', {
    viewModel: Item2,
    template: '<div class="col-md-12" data-bind="visible: $parent.activeView()===\'item-2\'"> <h1>Item 2</h1> <input data-bind="value: comment"/> <h3 data-bind="text: comment"></h3> </div>'
});

也许那是怎么回事?

首先要做的事情......我已经创建了一个小提示,显示了一些示例代码,以便您可以看到出现了什么问题。

https://jsfiddle.net/e427a7p2/1/

本质上我有两个组件,每个组件都有一个 comment 属性。问题是他们似乎共享相同的评论属性,所以当我改变其中一个时,其他也会改变。

要复制该问题,请执行以下步骤:

  1. 点击第1项并记下输入框的内容和下面的文字。
  2. 点击第2项并记下输入框的内容和下面的文字。
  3. 返回第1项(单击标题以返回)并更改输入框中的文本。应该发生的是下面的文字发生了变化,但它并没有改变。
  4. 返回第2项(点击标题返回)并记下输入框的内容和下面的文字。它与我们在步骤3中更改的输入相同。
  5. 更改第2项输入框的内容,您可以看到其下方的文字发生变化。
  6. 返回第1项(单击标题以返回)并注意输入框的内容与刚更改后的内容相同。以下文字仍未改变。
  7. 因此,出于某种原因,虽然它们意味着是单独的viewModel,但它们正在共享(类似)comments属性。

    知道我在这里做错了吗?

    组件的HTML如下:

    <div id="item-1">
        <div class="col-md-12" data-bind="with: Item1, visible: activeView() === 'item-1'">
            <h1>Item 1</h1>
            <input data-bind="value: comment" />
            <h3 data-bind="text: comment"></h3>
        </div>
    </div>
    
    <div id="item-2">
        <div class="col-md-12" data-bind="with: Item2, visible: activeView() === 'item-2'">
            <h1>Item 2</h1>
            <input data-bind="value: comment" />
            <h3 data-bind="text: comment"></h3>
        </div>
    </div>
    

    和JS如下:

    var Item1 = function Item1() {
        var self = this;
    
        console.log(self);
    
        self.title = ko.observable('Item 1');
        self.comment = ko.observable('comment: item 1');
    }
    
    var Item2 = function Item2() {
        var self = this;
    
        console.log(self);
    
        self.title = ko.observable('Item 2');
        self.comment = ko.observable('comment: item 2');
    }
    
    ko.components.register('menu', {
        viewModel: Menu,
        template: {element: 'menu'}
    });
    
    ko.components.register('item-1', {
        viewModel: Item1,
        template: {element: 'item-1'}
    });
    
    ko.components.register('item-2', {
        viewModel: Item2,
        template: {element: 'item-2'}
    });
    
    var VM = function VM() {
        var self = this;
    
        self.activeView = ko.observable();
    
        Sammy(function() {
            this.get('/', function(context) {
                self.activeView('menu');
            });
    
            this.get('#/item-1', function(context) {
                self.activeView('item-1');
            });
    
            this.get('#/item-2', function(context) {
                self.activeView('item-2');
            });
        }).run();
    };
    
    ko.applyBindings(new VM());
    

    谢谢,

    亚当

1 个答案:

答案 0 :(得分:0)

项目可以用html定义。最好的方法是在脚本标记中。这样可以确保模板可以包含表等。

<script id="item-1" type="text/template">
  <div>markup here</div>
</script>

在你的小提琴中,你定义了模板(第1项和第2项)。将视图模型绑定到整个文档ko.applyBindings(new VM());,这会将ViewModel绑定到项模板,这是无效的。

你的HTML应该是这样的

<body>
  <div id="container">
    <item-1></item-1>
  </div>
  <div id="item-1">item template id</div>

<script type="text/javascript">
  // only bind view model to the container and not to the templates
  ko.applyBindings(new ViewModel(),document.getElementById("container"));
</script>
</body>

更新小提琴:https://jsfiddle.net/e427a7p2/2/