0

バインドしている場合、ノックアウト js に問題があります。エラーなしでバインディングのサブ プロパティを参照できるため、バインディングをかなり自由に使用します。

問題の 1 つの原因は、if バインディングによって追加される DOM 要素にイベント ハンドラーなどを登録することです。基本的に、if バインディングによって追加された要素が DOM に追加されたときに、コールバックを取得する必要があります。livequery jquery プラグインを使用してみましたが、要素が 2 回追加されているようです。これを示すために、いくつかのサンプルコードを思いつきました。

ノックアウトのドキュメントには、次のように明確に記載されています。

「ただし、if バインディングは、DOM に含まれるマークアップを物理的に追加または削除し、式が true の場合にのみバインディングを子孫に適用します。」

http://knockoutjs.com/documentation/if-binding.html

ただし、次のコードでは、インライン スクリプトのアラートが実行されます。

JS:

var vm = {
    val: ko.observable(false),
    someText: ko.observable("some text"),
};

ko.applyBindings(vm, document.getElementById("d1")

HTML:

<div id="d1" data-bind="if: val">
   <span data-bind="text: someText"></span>
   <script>alert("here")</script>
</div>​
4

2 に答える 2

4

あなたは本質的に、この引用であなた自身の質問に答えました:

「ただし、if バインディングは、DOM に含まれるマークアップを物理的に追加または削除し、式が true の場合にのみバインディングを子孫に適用します。」

この引用はバインディングの動作を明確に示していますが、他の JavaScript やブラウザーの機能については何も述べていません。Knockout のドメインはバインディングであり、それ以外のものではないため、これは完全に理にかなっています。Knockout が読み込まれるまでに、ブラウザはすでにそのアラート ステートメントを実行しています。そして、Knockout がそれを DOM ツリーに戻すたびに、そのアラート ステートメントを実行します。

このような要素を Knockout と組み合わせて使用<script>​​することは悪い習慣であり、予期しない動作につながる可能性があります。やりたいことは、バインディングである Knockout のドメインで意図した動作を表現することです。あなたの場合、これはafterRenderバインディングに適合します:

<div id="d1" data-bind="if: val">
   <span data-bind="text: someText, afterRender: alert('here')"></span>
</div>​

valの場合true、インナー<span>がレンダリングされ、afterRenderイベントが発生します。

の場合、インナーvalはレンダリングされず、イベントは発生しません。false<span>afterRender

于 2012-08-22T20:30:47.040 に答える
1

わかりました、私は何をする必要があるかを理解しました。どうやら 'if' バインディングは、実際にはテンプレート バインディングのネイティブ/単純化された拡張です。

http://knockoutjs.com/documentation/template-binding.html

テンプレート バインディングには、テンプレート全体が DOM に追加された後に実行される関数を渡すことができる afterRender オプションもあります。

私のコードは次のようになります。

<div data-bind="template: {if: val, afterRender: func}">

ノート:

これは、'with' バインディング、そしてもちろん 'foreach' バインディングを使用しても機能します。

于 2012-08-22T22:21:49.437 に答える