2012-02-06 15 views
1

私はknockoutjsの使用を開始しましたが、動的なツリービューを構築しようとしています。簡素化するために、問題に関連していないものはすべて削除しました。ツリービューはネストされたULタグで構成されます。Knockoutjsツリービュー遅延ロード:子ノードが表示されない

HTML:

<div id="pnlDestinations"> 
    <ul data-bind="template: { name: 'GroupTemplate', foreach: Groups }"></ul> 
</div> 

<script type="text/html" id="GroupTemplate"> 
    <li> 
     <a href="#" data-bind="text: GroupName, click: function() { RetrieveDestinations($data); }"></a> 
     <ul data-bind="template: { name: 'DestinationTemplate', foreach: Destinations }"></ul> 
    </li> 
</script> 

<script type="text/html" id="DestinationTemplate"> 
    <li> 
     <a href="#" data-bind="text: DestinationName"></a> 
    </li> 
</script> 

コード:

function ViewModel(groups) { 
    Groups = ko.mapping.fromJS(groups); 
    RetrieveDestinations = function (group) { 
     $.getJSON('GetDestinations?id=' + group.GroupId(), function (data) { 
      group.Destinations(ko.mapping.fromJS(data)); 
     }); 
    } 
} 

$(function() { 
    $.getJSON("GetGroups", function (data) { 
     ko.applyBindings(new ViewModel(data)); 
    }); 
}); 

は、だから私は(2つのテンプレートを使用して)二つのレベルでツリービューを結合していますが、私は唯一の1つ上のレベルを取得しています」 GetGroups "(宛先は存在しますが、空の配列です)。

宛先は、グループがクリックされたときにRetrieveDestinations()メソッドで取得され、グループ内の空の配列を置き換える必要があります。しかし、彼らは私のツリービューに表示されません。

"GetGroups"に宛先を含めると、すべてが正しくレンダリングされるため、ツリービューのバインディングは正しいはずです。

答えて

3

ko.mapping.fromJS与えられた配列がobservableArrayに変換する場合、

したがって、group.Destinations(ko.mapping.fromJS(data))を実行するときは、Destinations observableArrayの値をobservableArrayと同じに設定します。基本的には、これは2回ラップされたことを意味します。

あなたはgroup.Destinations(ko.mapping.fromJS(data)())

jsFiddleような何かを行うことができます許可されていませんが、あなたのコードは目的地を更新するために、マッピング・プラグインを使用するように単純化され、ここで、現時点で保存しますが、(setTimeoutsは、AJAXをシミュレートする):

<div id="pnlDestinations"> 
    <ul data-bind="foreach: Groups"> 
     <li> 
      <a href="#" data-bind="text: GroupName, click: $root.RetrieveDestinations"></a> 
      <ul data-bind="foreach: Destinations"> 
       <li> 
        <a href="#" data-bind="text: DestinationName"></a> 
       </li>   
      </ul> 
     </li> 
    </ul> 
</div> 

ViewModelには:

function ViewModel(groups) { 
    this.Groups = ko.mapping.fromJS(groups); 
    this.RetrieveDestinations = function (group) { 
     setTimeout(function() { 
      //fake data 
      var name = group.GroupName(), 
       data = [ 
        { DestinationName: name + "-1" }, 
        { DestinationName: name + "-2" }, 
        { DestinationName: name + "-3" } 
       ]; 
      ko.mapping.fromJS(data, {}, group.Destinations); 
      group.Destinations.push({ DestinationName: "new" }); 
     }, 100); 
    }; 
} 

$(function() { 
    setTimeout(function() { 
     var data = [ 
      { GroupName: "Group1", Destinations: [] }, 
      { GroupName: "Group2", Destinations: [] }, 
      { GroupName: "Group3", Destinations: [] } 
      ]; 
     ko.applyBindings(new ViewModel(data)); 
    }, 100);  
}); 
+0

はい、これら二つは、()のトリックをした、私は今働いて、ツリービューを持っています!どうもありがとう。素晴らしい説明! – NetWave

+0

私は奇妙な副作用に気付きました、RP Niemeyer ...コード 'group.Destinations.push({DestinationId:0、DestinationName:" New "});' doens't work。メッセージは:オブジェクトがプロパティまたはメソッド 'push'をサポートしていません。直ちに宛先を検索すると機能します。 – NetWave

+0

おそらくあなたはjsFiddleに何かを置くことができますか? –

関連する問題