</div> <script type="text/html" id="GroupTemplate"> "> </div> <script type="text/html" id="GroupTemplate"> "> </div> <script type="text/html" id="GroupTemplate"> " />

Knockoutjsツリービュー遅延読み込み:子ノードが表示されない

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

html:

<div id="pnlDestinations">
    
    </div> <script type="text/html" id="GroupTemplate">
    • </script> <script type="text/html" id="DestinationTemplate">
    • </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つのレベル(2つのテンプレートを使用して)ツリービューをバインドするが、私は "GetGroups"(宛先は存在しますが、空の配列です)で1つのレベルを取得しています。

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

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

      1

      1 答え

      ko.mapping.fromJS when given an array is going to turn it into an observableArray.

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

      You could do something like group.Destinations(ko.mapping.fromJS(data)())

      jsFiddleは現在のところ保存を許可していませんが、ここでは、マッピングプラグインを使用して送り先を更新するためのコードを簡略化しています(AJAXをシミュレートするためのsetTimeouts)。

      <div id="pnlDestinations">
          
      </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);     
      });
      
      3
      追加された
      多分あなたはjsFiddleに何かを置くことができますか?
      追加された 著者 RP Niemeyer,
      上記の更新されたコードは、マッピングプラグインを使用して ko.mapping.fromJS(data、{}、group.Destinations)を使用して配列を更新します。このコードを試してください。私はあなたがあなたのプッシュをしているかどうかはわかりませんが、これが役立つかどうかを見てください。私たちは、jsFiddleが再びセーブを許可したときに、それをフィドルで行うことができます。
      追加された 著者 RP Niemeyer,
      確かに...今はすべて正常に動作していますか?
      追加された 著者 RP Niemeyer,
      はい、その2つ()はトリックをしました、私は今作業ツリービューを持っています!どうもありがとう。素晴らしい説明!
      追加された 著者 NetWave,
      私は奇妙な副作用に気づいた、RP Niemeyer ...コード group.Destinations.push({DestinationId:0、DestinationName: "New"}); は動作しません。メッセージは:オブジェクトがプロパティまたはメソッド 'push'をサポートしていません。直ちに宛先を検索すると機能します。
      追加された 著者 NetWave,
      jsFiddleでajaxリクエストをシミュレートできますか?上記の例では、 group.Destinations(ko.mapping.fromJS(data)()); の後に group.Destinations.push({DestinationId:0、DestinationName: "New "}); (すぐに検索されたリストに余分な項目を追加するために)例外は 'push'にスローされます。私がDestの値を置き換えない(コメントアウトする)と、元の空の配列のままになります。
      追加された 著者 NetWave,
      素晴らしい、本当に...あなたのコードはとてもクリーンです!私はなぜ私が最初にテンラーートが必要だと思ったのだろうかと思う: - /私の防衛で:まだノックアウトを学ぶ。あなたのコードはうまくいきました。だから、あなたのおかげで、私はなぜ:GetGroupsサービスのコードを、空の配列ではなく宛先としてnullを返すように変更しました。私はこの値を使ってRetrieveDestinationsを呼び出す必要があるかどうかをテストしました。配列が空であるかどうかをテストすると、グループに宛先がまったくない場合、グループがクリックされるたびにajax要求が発生します。
      追加された 著者 NetWave,
      したがって、要約すると、ターゲット(値null)を実際の配列に置き換えることは、バインディングがキックインするのに十分ではありましたが、push()は機能しませんでした...
      追加された 著者 NetWave,
      はい、あなたの努力のおかげで!
      追加された 著者 NetWave,