2013-03-20 62 views
5

我试图做一些复杂的绑定与淘汰赛(至少像我这样的新手)。knockout.js递归绑定

考虑以下数据:

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> 

好吧,这是比较容易的部分。

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

我应该如何用knockout解决这个问题?

我已经把我至今对的jsfiddle样本:http://jsfiddle.net/graphicsxp/qXZjM/

+0

一个想法,就是里面使用模板使用相同的选择框,当选择和孩子有个项目是模板追加到表元素。目前还不清楚我将如何去做,但你认为我走在正确的轨道上吗? – Sam 2013-03-20 18:30:12

回答

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> 

这里是the fiddle


更新:

可以使用computed轻松地做到这一点,并删除从视图中的逻辑(我认为在这种情况下更好),然后将if绑定到它。

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

如果你想要把无论是在if块,你可以,你只需要包括括号。其原因是可观察量是函数;如果您仅使用单个引用,则可以将它们排除在外,但它们需要“向下钻取”其属性。

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

这里是我脑海中updated fiddle

+0

非常感谢,看起来很棒!这几乎是我所需要的。但只有一件事,我无法使用映射插件使用它,而您使用了硬编码的Person函数。你能指点我做错了什么吗? jsfiddle here:http://jsfiddle.net/graphicsxp/qXZjM/ – Sam 2013-03-20 21:28:10

+0

实际上忽略了我的评论,现在确实有效。我只需要将selectedChild属性设置为ko.observable()。非常感谢 ! – Sam 2013-03-20 21:50:13

+0

最后一个问题:如何修改if绑定,以便模板只显示selectedChild是否至少有一个孩子?我已经尝试过,如果:selectedChild && selectedChild.children.length> 0但不起作用....任何想法? – Sam 2013-03-20 22:14:34