0

私は Knockout JS を初めて使用し、ブートストラップ モーダルと一緒に使用すると、何時間もの調査にもかかわらず解決できなかった問題に遭遇しました。

ここに私の問題があります:私はネストされたビューモデルを使用していますが、モーダルを表示に設定する直前または直後に、ネストされた vm (監視可能かどうかに関係なく) の変数を更新しようとすると、これら変数は初期値にリセットされます。アイデアを提供するためのサンプルコードを次に示します。

  ###########Javascript########################
  function ViewModelA() {
      self = this;
      self.B = ko.observable(new ViewModelB(self));

      self.ShowB(){
         self.B.Show();
      };
  };

  function ViewModelB(parent){
      self = this;
      self.varOne = ko.observable();
      var varTwo = null;

      self.Show = function(){
         self.GetData();
         $("#modalB").modal('show');
      };

      self.GetData = function(){
         //Ajax call that sets varOne and varTwo
      };

  };

  var A = new ViewModelA();
  ko.applyBindings(A,document.getElementById('modalA'));

 ##############HTML###############################
 <div id="modalA" class="modal fade" tabindex="-1" role="dialog" aria-   labelledby="myModalLabel" aria-hidden="true">
     <div class="modal-dialog">
         <div class="modal-content">
             <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                <h3 id="myModalLabel">Modal header</h3>
             </div>
             <div class="modal-body">
             ...

modalB の HTML コードはかなり似ていますが、最初の div にdata-bind="B"タグが追加されています。

ユーザーが ModalA のボタンをクリックすると、ModalA の Show() 関数がトリガーされ、次に AJAX 呼び出しから ModalB のオブザーバブルが取り込まれ、ModalB が表示されるという考え方です。

上記の例では、Show() 関数内から GetData() を呼び出すと、モーダルの読み込みが完了すると、varOne と varTwo が初期値にリセットされます。代わりに、ViewModelB がインスタンス化されたときに (つまり、ModalA の Show 関数がユーザーによって呼び出される前に) GetData() を呼び出すと、新しい値が保持されます。

私はこの数日間、なぜこれが起こっているのか、そしてどのように対処するのが最善なのかを理解しようと頭を悩ませてきました. カスタム バインディング ハンドラ、レンダリング テンプレート、およびブートストラップ モーダル「ロード」イベントの呼び出しについて調べました。

誰かがこのシナリオに出くわしましたか? 前もって感謝します!

4

1 に答える 1

0

提案を行う前に、提起する必要があるいくつかの点があります。

  • modalB は modalA内にありますか? そうでない場合は、データ バインディングを にのみ適用するため、Knockout によってデータ バインドされません#modalA
  • この行
    self.B = ko.observable(ViewModelB(self));
    は実際には , である
    self.B = ko.observable(new ViewModelB(self));
    べきではありませんnew ViewModelBか?
  • ViewModelB.ShowBである必要がありViewModelB.Showますよね?それとも呼び出しがself.B.Show間違っていますか?また、私の JavaScript が間違っていますか、それともキーワードがself.ShowB()欠落しself.GetData()ていますか?function

さて、あなたの例では JavaScriptViewModelB.varOneは観察可能であり、観察可能でViewModelB.varTwoはありません

最初にそれを呼び出すViewModelB.Showと、これら2つの変数の値を取得するためにajax呼び出しが行われます。この非同期呼び出しが行われるとすぐに、ブラウザは から出てViewModelB.GetData()から戻りViewModelB.Show、modalB を表示します。

ajax 呼び出しが返され、ハンドラー関数 (表示されていませんが、これは非常に適切です) が応答を使用して値を設定すると、それらの監視可能な変数のみDOM で更新されます。サンプル JavaScript の場合ViewModelB.varTwo、DOM で更新されることはありません。

ViewModelB.varOne代わりに、との両方ViewModelB.varTwoが観測可能であることを確認することをお勧めします。

別の方法として$("#modalB").modal('show');、ajax 呼び出しが返されたときにのみ呼び出すコールバック関数を配置することもできますが、modalB の表示に望ましくない遅延が発生します。

于 2015-07-28T08:39:00.030 に答える