2012-04-25 6 views
24

私はドラッグアンドドロップとajaxのアップロードにpluploadを使用するノックアウトバインディングハンドラを持っています。ノックアウトバインディングハンドラのティアダウン機能?

pluploadスクリプトを使用するには、イベントリスナーをDOM要素にバインドするpluploadのインスタンスを作成します。

これは問題なく動作します。

しかし、私は "フォルダ"のリストを持っています。私がフォルダをクリックすると、そのフォルダ内のファイルのリストを表示します。 foreachを使用してselectedFolder()。documentsをバインドして、同じDOM要素を再利用します。

私の問題は、バインディングハンドラでは、init関数ですべてのpluploadを行い、DOM要素を再利用するため、複数のイベントハンドラがバインドされてしまうことです。これにより、すべてのハンドラにドラッグアンドドロップイベントが送信されます。つまり、レンダリングされたファイルリストにファイルをドロップすると、以前にレンダリングされたすべてのファイルリストに対してもドロップイベントが発生します。

私が探しているのは、バインディングハンドラのティアダウンまたはクリーンアップ機能です。そのため、ファイルリストが未レンダリングされたときはいつでもすべてのイベントを登録解除できます。

アンレンダーリングが検出されないことがありますか?どのように私はこれを処理するだろうか?グローバルインスタンスを持たない方が好きです。これは、同時に複数の場所でバインディングを使用できなくなるためです。

ご迷惑をおかけして申し訳ございません。私は自分の携帯電話のATMにいる。

乾杯!

答えて

32

KOが(テンプレートが再レンダリングされたときのように)要素を削除するときに実行されるハンドラを登録できます。あなたがバインドされていると、あなたが希望何でもクリーンアップコードを実行する機会を持っているでしょう要素のためにdisposeコールバックを登録しますあなたの「初期化」機能では、

ので
//handle disposal (if KO removes by the template binding) 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $(element).datepicker("destroy"); 
    }); 

:それは次のようになります。

+0

それは間違いなく私の問題を解決するでしょう。残念だけど、それは解放されていない。ありがとうRP! –

+0

独自のDOM操作(シングルページアプリケーションでは共通)を行う他のライブラリと組み合わされている場合は、以下のjQueryのアプローチを考慮して、ノーマルでトリガされたものだけでなくDOMを削除することもできます。すでにjQueryを参照している場合に便利です。 –

3

ここで提供される解決策は、ノックアウトがDOMノードを削除するもの(つまり、テンプレートを再作成する場合)のみであると考えています。私は特定の条件の下でトリガーするのは難しい時期でした。要素がどのように削除されたかにかかわらずコールバックを実行する必要があるシナリオがあります。ノックアウトであろうと、jQuery.html()などによるものであろうと(特に単一ページアプリケーションで)

jQueryの助けを借りて、このようなフックを追加するための別のアプローチを作成しました。特殊イベントAPI(よくわかっているのはhere)を使用して、特定のイベントがDOMノードのremoved(ティアダウン時に発生するイベント)のときに実行されるメソッドを追加できます。

あなたはjQueryを使って一緒にノックアウトを使用している場合、あなたはこのような何かを探すように結合ノックアウトにこれをラップすることができます:

ko.bindingHandlers.unload = { 
    init: function (element, valueAccessor) { 
     var eventName = 'your_unique_unLoad_event'; // Make sure this name does not collide 
     if (!$.event.special[eventName]) { 
      $.event.special[eventName] = { 
       remove: function (o) { 
        o.data.onUnload() 
       } 
      }; 
     } 
     $(element).on(eventName, { onUnload: valueAccessor()}, $.noop); 
    } 
}; 

あなたは、このような任意の要素でこれを使用することができます。

<div id="withViewModelMethod" data-bind="unload: aMethodOnMyViewModel" /> 
<div id="withInLineMethod" data-bind="unload: function() { /* ... */ }" /> 

このクレジットはSO postです。

+0

どうしたらいいのかわかりません** var eventName = '_unique_unLoadEventName ____ 12345'; **私は似たような状況に遭遇したので理解しようとしています。 – nimgrg

+0

それは私が帽子から引き出した文字列です。あなたが望むものであれば何でもかまいません。私はそれが一意であり、他のプラグインや独自のイベントハンドラを追加するサードパーティのコードと衝突しないようにしたかっただけです。この例ではやや誇張されています。 –

+0

'_unique_unLoadEventName____12345'を 'your_unique_unLoad_event'に変更するだけです –

関連する問題