5

我正在尝试用淘汰赛做一些复杂的绑定(至少对于像我这样的新手来说)。

考虑以下数据:

var originalData = {
id: 1,
name: "Main",
children: [ { id: 2, name: "bob", children: []}, { id: 3, name: "ted", children: [{id: 5, name:"albert"}, {id: 9, name: "fred"}]} ],
selectedChild:  { id: 2, name: "bob" }
};

<table>
<tr>
    <td data-bind="text: name"></td>
</tr>
<tr data-bind="if: children().length > 0">
    <td>
        <select data-bind="options: children,
            optionsText: function(item){
                return item.name;
                    }, 
            optionsCaption: 'Choose...'"></select>       
    </td>
</tr>

好的,这是最简单的部分。

困难的部分是,每当在列表中选择一个项目时,如果该项目有子项,则下方应出现一个新的选择框。它的数据源将是第一个选择框中所选项目的子项。当然,它可以以任何深度继续下去。

我应该如何通过淘汰赛解决这个问题?

我已经汇总了迄今为止在 jsfiddle 上的示例:http: //jsfiddle.net/graphicsxp/qXZjM/

4

1 回答 1

9

您可以通过将模板放入script标签中来在淘汰赛中使用递归模板。标签中的模板script可以引用自己,如下所示:

<div data-bind="template: 'personTemplate'"></div>

<script type="text/ko" id="personTemplate">
    <span data-bind="text: name"></span>
    <select data-bind="options: children, optionsText: 'name', optionsCaption: 'Choose',  value: selectedChild"></select>
    <!-- ko if: selectedChild -->
    <div data-bind="template: { name: 'personTemplate', data: selectedChild }"></div>
    <!-- /ko -->
</script>

这是小提琴


更新:

您可以使用 acomputed轻松执行此操作,并从视图中删除逻辑(我认为在这种情况下更好),然后将其绑定if到它。

self.showChildren = ko.computed(function() {
    return self.selectedChild()
        && self.selectedChild().children().length > 0;
});

如果你想把两者都放在if块中,你可以,你只需要包括括号。原因是 observables 是函数。如果您只使用单个引用,则敲除允许您排除它们,但它们需要“深入”到它们的属性。

if: selectedChild() && selectedChild().children().length > 0

这是更新的小提琴

于 2013-03-20T20:10:35.623 回答