2013-03-20 14 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> 

[OK]を、それは簡単な部分でした。

難しい部分は、リスト内のアイテムが選択されるたびに、このアイテムに子がある場合は新しい選択ボックスがその下に表示されることです。そのデータソースは、最初の選択ボックスで選択された項目の子になります。もちろん、どんなレベルの深さでも続けることができます。

ノックアウトでこの問題を解決するにはどうすればよいですか?

私は一緒に私はjsfiddleに、これまで持っているもののサンプルを入れている:http://jsfiddle.net/graphicsxp/qXZjM/

+0

1アイデアがあり、内部に同じ選択ボックスで、テンプレートを使用して、子供を持つ項目が選択されたときに、テーブル要素にそのテンプレートを追加することです。私はそれをどうやってやろうとしているのかはまだはっきりしていませんが、私は正しい方向にいると思いますか? – Sam

答えて

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

+0

は実際には私のコメントを無視しています。 selectedChildプロパティをko.observable()に設定するだけでした。どうもありがとう ! – Sam

+0

最後の質問:selectedChildに少なくとも1つの子がある場合にのみテンプレートが表示されるように、ifバインディングをどのように変更しますか?私はkoを試しました:selectedChild && selectedChild.children.length> 0しかし、それは動作しません....任意のアイデア? – Sam