Knockout js foreach绑定扩展/崩溃

时间:2015-07-14 03:54:32

标签: javascript html knockout.js

我已经阅读了几个教程并尝试了几个小时试图让它工作。我的目标是让多个链接在单击时展开/折叠。到目前为止,我有以下内容:

HTML:

<ul data-bind="foreach: items">
    <a href="#" data-bind="click: $parent.toggle, text: $parent.linkLabel"></a>        
    <button data-bind="text: name, click: $parent.clickTask"></button>
    <div data-bind="visible: $parent.expanded">
        <input data-bind="value: name"></input>
    </div>
</ul>

JS:

var viewModel = function() {
    var self = this;

    self.items = [{"name":"bruce","id":1},{"name":"greg","id":2}]

    self.expanded = ko.observable(false);

    self.linkLabel = ko.computed(function () {
        return self.expanded() ? "collapse" : "expand";
    }, self);      

    self.toggle = function (item) {
        self.expanded(!self.expanded());
    };
};

ko.applyBindings(new viewModel());

JSFiddle Here

我现在理解我在父母身上有扩展状态,这就是为什么一切都会扩展/崩溃的原因。如何让每个项目跟踪自己的扩展/拼贴状态?

2 个答案:

答案 0 :(得分:3)

您正在通过引用single dependency来为所有可观察对象创建parent,这是问题所在。

  

因此,您需要为每个列表项创建独立的依赖项并进行制作   使用引用当前上下文的$data。    这里的技巧是为每个listitem创建一个实例

查看:

<ul data-bind="foreach: items"> <a href="#" data-bind="click: toggle, text:linkLabel"></a> 
    <button data-bind="text:name"></button>
    <div data-bind="visible:expanded">
        <input data-bind="value:name"></input>
    </div>
</ul>

<强>视图模型:

function Sample(item) {
    var self = this;
    self.name = ko.observable(item.name);
    self.id = ko.observable(item.id);
    self.expanded = ko.observable(false);
    self.toggle = function (item) {
        self.expanded(!self.expanded());
    };
    self.linkLabel = ko.computed(function () {
        return self.expanded() ? "collapse" : "expand";
    }, self);
}

var viewModel = function () {
    var self = this;

    var json = [{
        "name": "bruce",
        "id": 1
    }, {
        "name": "greg",
        "id": 2
    }]

    var data = ko.utils.arrayMap(json, function (item) {
        return new Sample(item); // making things independent here 
    });
    self.items = ko.observableArray(data);
};

ko.applyBindings(new viewModel());

工作样本 here

答案 1 :(得分:1)

我只是在解决一些非常相似的问题,我认为有一种方法可以在不向ViewModels添加任何逻辑的情况下解决。

以下代码适用于每行都可扩展的表:

<tbody data-bind="foreach: payments">
    <tr style="cursor: pointer" data-toggle="collapse" data-bind="attr: {'data-target': '#row' + $index()}">
        <td>Column 1 content</td>
    </tr>
    <tr data-bind="attr: {id: 'row' + $index()}" class="collapse">
        <td>
            Detail....
        </td>
    </tr>
</tbody>

它使用2次 attr 绑定,一次用于定义生成的详细信息行的ID,一次用于设置折叠切换的数据目标

您的示例可以通过以下方式进行修改,您根本不需要“扩展”观察。

<ul data-bind="foreach: items">
<a href="#" data-toggle="collapse" data-bind="attr: {'data-target': '#row' + $index()}"></a> 
    <button data-bind="text:name"></button>
    <div data-bind="attr: {id: 'row' + $index()}" class="collapse">
        <input data-bind="value:name"></input>
    </div>
</ul>