ko.applyBindingsを呼び出して部分ビューをバインドできますか?


258

私はKnockoutJSを使用しており、メインビューとビューモデルがあります。ダイアログ(jQuery UIの1つ)に、別の子ビューモデルがバインドされる別のビューをポップアップ表示させたい。

ダイアログコンテンツのHTMLはAJAXを使用して取得されるのでko.applyBindings、リクエストが完了したら呼び出せるようにしたいと思います。また、子ビューモデルを、ダイアログdiv内のajaxを介して読み込まれたHTMLの一部だけにバインドしたいと思います。

これは実際に可能ですか、それともページが最初にロードされてからko.applyBindings一度呼び出されたときにすべてのビューとビューモデルをロードする必要がありますか?

回答:


431

ko.applyBindings ルートとして使用するDOM要素である2番目のパラメーターを受け入れます。

これにより、次のようなことが可能になります。

<div id="one">
  <input data-bind="value: name" />
</div>

<div id="two">
  <input data-bind="value: name" />
</div>

<script type="text/javascript">
  var viewModelA = {
     name: ko.observable("Bob")
  };

  var viewModelB = {
     name: ko.observable("Ted")
  };

  ko.applyBindings(viewModelA, document.getElementById("one"));
  ko.applyBindings(viewModelB, document.getElementById("two"));
</script>

したがって、この手法を使用して、viewModelをダイアログにロードする動的コンテンツにバインドできます。全体として、applyBindings複数のイベントハンドラーがアタッチされるため、同じ要素に対して複数回呼び出さないように注意する必要があります。


17
バインディングを途中で削除したい場合は、呼び出しko.cleanNode(document.getElementById("one")を行ってクリーンアップするかko.removeNode(document.getElementById("one")、クリーンアップしてDOMからノードを削除します。
Michael Berkompas

7
ただ、ノートcleanNoderemoveNodeイベントハンドラを削除しないであろうが、ので、いくつかの注意を払ってください。場合によっては、これらの領域でtemplateまたはwithバインディングを使用して、新しい要素をレンダリングすることが望ましい場合があります。
RP Niemeyer

7
現在、KOに欠けているものです。特にセクションを「再バインド」することは意図していません。ただし、KOは、参照されている場合、jQueryを使用してイベントをアタッチ$(element).unbind();するため、すべてのハンドラーを削除できます。
RP Niemeyer 2012年

5
これらの関数(applyBindings、cleanNode、removeNode)はどこに文書化されていますか?私はknockoutjs.comでそれらの関数シグネチャを見つけることができません。
EricP 2013年

2
これがドキュメンテーション内のどこかに簡単に配置できるとしたらいいでしょう。私はそれについての言及を見さえしませんでした。
Travis Kaufman

61

ニーマイヤーの答えは質問に対するより正しい答えです、次のことできます:

<div>
  <input data-bind="value: VMA.name" />
</div>

<div>
  <input data-bind="value: VMB.name" />
</div>

<script type="text/javascript">
  var viewModels = {
     VMA: {name: ko.observable("Bob")},
     VMB: {name: ko.observable("Ted")}
  };

  ko.applyBindings(viewModels);
</script>

つまり、DOM要素を指定する必要はなく、次のように複数のモデルを同じ要素にバインドすることもできます。

<div>
  <input data-bind="value: VMA.name() + ' and ' + VMB.name()" />
</div>

4
また、「with」を使用して、ページの領域を個々のモデルに割り当てることもできます
-data

3
@flamingpenguin:はい、しかし、with安いものではありません、以下を参照してください。リンク
MHU

7

実行時にカスタムモデルを要素にバインドすることに成功しました。コードはこちら:http : //jsfiddle.net/ZiglioNZ/tzD4T/457/

興味深い点は、定義していない要素にdata-bind属性を適用することです。

    var handle = slider.slider().find(".ui-slider-handle").first();
    $(handle).attr("data-bind", "tooltip: viewModel.value");
    ko.applyBindings(viewModel.value, $(handle)[0]);

ko 2.3で問題が発生した場合、上記のコードはグローバルko.applyBindings()を適用したときに呼び出されるカスタマーハンドラーにあります。そのため、「同じ要素にバインドを複数回適用することはできません。」というエラーが表示されます。私はまだエラーが発生する理由を理解しようとしています。同じ変数へのバインディングを複数回、それぞれ異なる要素に適用することはできませんか?
ZiglioUK 2013

これは動作しないko 2.3のバージョンです:jsfiddle.net/ZiglioNZ/tzD4T/458
ZiglioUK

部分ビューにapplyBindingを呼び出す前にko.cleanNode()への呼び出しを追加しても効果がないようです:jsfiddle.net/ZiglioNZ/tzD4T/459
ZiglioUK

解決済み:applyBindingsを呼び出す必要さえありませんでした!
ZiglioUK 2013

私はノックアウトjsソースコードを編集し、関数が「同じ要素にバインディングを複数回適用することはできません。」と書いてある部分にコメントしました。これですべて正常に動作します...これはダーティなソリューションですが、ライブラリーに新しいので、私の問題に何度も適用しない方法がわかりません。
Geomorillo 2013年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.