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>

ここにフィドルがあります


アップデート:

a を使用しcomputedてこれを簡単に実行し、ビューからロジックを削除して (この場合はこれの方が良いと思います)、 をそれにバインドifできます。

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

両方をブロックに入れたい場合ifは、かっこを含めるだけでかまいません。これは、オブザーバブルが関数であるためです。ノックアウトを使用すると、単一の参照のみを使用している場合にそれらを除外できますが、プロパティに「ドリルダウン」する必要があります。

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

これが更新されたフィドルです

于 2013-03-20T20:10:35.623 に答える