2016-06-25 9 views
1

行を上下矢印で選択できるテーブルがあり、行が選択されるとこれがオフになり、ajax経由でレコードが取得されます。keydownイベントリスナーからデバウンス関数を抽出する

ユーザーがスパム送信するajaxリクエストを停止するには、私がディレクティブから呼び出しているデバウンス機能があります。これはkeydownイベントによってトリガーされます。これはすべて機能しますが、必要な方法ではありません。私は、デバウンス関数が呼び出される前にpreventDefaultを呼び出すようにします。したがって、ユーザーは遅れなく行を上下に移動でき、遅れてもAJAXはまだ起動します。

私はこれを可能にするために私のコードを抽出する必要があると思うが、いくつかのことを試みた後、私はそれを働かせることはできない。ディレクティブでは

:これはオリジナルバージョンであるコントローラで

$('table').keydown(scope.debounce(function (e) { 

    if(e.keyCode == 38) { // Up arrow 
     // Do Ajax stuff 

     e.preventDefault(); 
     e.stopPropagation(); 
    } 

    if(e.keyCode == 40) { // Down arrow 
     // Do Ajax stuff 

     e.preventDefault(); 
     e.stopPropagation(); 
    } 

}, 250)); 

$scope.debounce = function (fn, delay) { 
    var timer = null; 

    return function() { 
     var context = this, args = arguments; 
     clearTimeout(timer); 
     timer = setTimeout(function() { 
      fn.apply(context, args); 
     }, delay); 
    }; 
}; 

私はKeyDownイベントで呼び出される関数を抽出しようとしたが、今それだけで遅延を無視しています。それを働かせる方法の周りに私の頭を得ることができません。コントローラで

:毎回のKeyDownイベントが押されているようですが、someFunctionが呼ばれたように見え

$('table').keydown(someFunction); 

function someFunction(e) { 
    e.preventDefault(); 
    e.stopPropagation(); 

    var blahblah = scope.debounce(function (e) { 

     if(e.keyCode == 38) { // Up arrow 
      // Do Ajax stuff 
     } 

     if(e.keyCode == 40) { // Down arrow 
      // Do Ajax stuff 
     } 

    }, 250); 

    blahblah(); 
} 
+0

を使用すると、var timer = setTimeout(function(){ fn.apply(context、args); }、delay)を使用できます。 }; –

+0

あなたは何を意味するのか完全に理解していませんが、あなたが言うようにコードを置き換えても機能しません。 – spengos

答えて

2

とそれだけで使用するblahblah呼ば新しいデバウンスラッパーを作成し、これは私がこれまで持っているものです正確に1回。

これらのデバウンサーのそれぞれは、キーストロークストロークにつき1回呼び出されるため、実際にはデバウンスは行われず、すべてが250ミリ秒遅れることになります。

someFunctionの外にblahblahを定義して、タイミングの問題を修正する必要があります。イベントオブジェクトをblahblahに渡すことを忘れないでください。

$('table').keydown(someFunction); 

var blahblah = scope.debounce(function (e) { 

    if(e.keyCode == 38) { // Up arrow 
     // Do Ajax stuff 
    } 

    if(e.keyCode == 40) { // Down arrow 
     // Do Ajax stuff 
    } 
}, 250); 

function someFunction(e) { 
    e.preventDefault(); 
    e.stopPropagation(); 

    blahblah(e); 
} 

また、追加の問題がありますが、上記の解決方法で対応してください。完全性のために、私はそれを指摘したいと思います。 someFunctionはOPに書かれていますが、名前のシャドーイングの問題があります。あなたはその後innerEが定義されていない、イベントオブジェクトに渡さずにblahblah()を呼び出すときに、このため

var blahblah = scope.debounce(function (innerE) { 

    if(innerE.keyCode == 38) { // Up arrow 
     // Do Ajax stuff 
    } 

    if(innerE.keyCode == 40) { // Down arrow 
     // Do Ajax stuff 
    } 

}, 250); 

:のポイントを証明するためにblahblahのパラメータeの名前を変更してみましょう。外側スコープのイベントオブジェクトeではありません。 var timer = nullの代わりに

+1

パーフェクト!どうもありがとうございました。私はちょうどそれの周りに私の頭を得ることができませんでした。私はそれを1つではなく2つの関数に抽出する必要がありました。 元のコードには小さな誤りがありました。それはblahblah(e)とされていた。私はそれを入力するときに 'e'を逃した。 – spengos

+0

うれしい私は助けた。私はタイミングの問題をデバッグしようとする気持ちを知っています。それはデバウンス、スロットル、および他のタイミングの問題は、あなたがそれに集中するほど複雑になるようです。正しい「解決策」は、これらの問題からしばらく離れていくことです。私は答えていないし、明日もこのことを見ても解決策はあなたに飛び火するだろうと確信しています:) – lastoneisbearfood

関連する問題