2016-06-25 7 views
1

위쪽/아래쪽 화살표를 사용하여 행을 선택할 수있는 테이블이 있습니다. 행을 선택하면이 값이 ajax를 통해 레코드를 가져옵니다.keydown 이벤트 리스너에서 debounce 함수 추출

사용자가 스팸성 아약스 요청을 멈추게하려면 지시문에서 호출하는 디버깅 기능이 있습니다. 이것은 keydown 이벤트를 통해 트리거됩니다. 이 모든 것이 작동하지만 필요한 방식은 아닙니다. 나는 debounce 함수가 호출되기 전에 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 = null을 사용할 수 있습니다. var timer = setTimeout (function() { fn.apply (context, args); }, 지연); }; –

+0

말의 뜻을 완전히 이해하지 못했지만 말한대로 코드를 대체 했으므로 작동하지 않습니다. – spengos

답변

2

과 만 사용하는 blahblah라는 새로운 디 바운스 래퍼를 생성 이것은 내가 지금까지 무엇을 가지고 정확하게 한 번.

각 debouncer는 keydown 스트로크 당 한 번 호출되므로 아무 것도 실제로 디 바운스되지 않으며 모든 것이 250ms 지연됩니다.

someFunction 외부에 정의해야 타이밍 문제가 해결됩니다. 이벤트 개체를 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에 쓰여진 방식으로, 당신은 이름 섀도 잉 문제가 있습니다. 의는 점을 보여 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()를 호출 할 때, innerE는 정의되지 않습니다. 바깥 쪽 범위의 이벤트 객체 e이 아닙니다.

+1

완벽! 고맙습니다. 지금은 너무 단순 해 보인다 :) 나는 그저 내 머리를 잡지 못했다. 나는 그것을 단지 하나가 아닌 두 개의 함수로 추출해야했습니다. 예, 원래 코드에 약간의 오류가있었습니다. 그것은 blahblah (e)로되어있었습니다; 나는 'e'를 타이핑 할 때 그것을 놓쳤다. – spengos

+0

다행입니다. 나는 타이밍 문제를 디버그하려고하는 느낌을 안다. 그것은 디 바운싱, 스로틀 및 기타 타이밍 문제가 더 집중할수록 더 복잡하게 보입니다. 올바른 "해결책"은 잠시 이러한 문제에서 벗어나는 것입니다.내가 대답하지 않고 내일 다시 보게되면 해결책이 너무 뛰어날 것입니다. :) – lastoneisbearfood