2012-11-03 2 views
0

일부 입력에 바인딩 된 관찰 가능 항목이 있으며 때로는 값 변경이 너무 빠르기 때문에 최종 사용자는 읽을 시간이 없습니다. 그래서 나는 입력 변화의 속도를 제한하고 싶다.knockout.js의 사용자 지정 스로틀 익스텐더

하지만 스로틀은 병목 목이며 조절 된 관측 값은 변경되는 동안 전혀 변경되지 않으므로 스로틀이 아닙니다. 첫 번째 변경 사항이 즉시 적용되도록 지연 조정 후 변경 될 수 있도록 사용자 지정 스로틀을 갖고 싶습니다 (물론 현재 시간이 지연된 후에 매번 변경 될 수 있습니다).

지금까지 사용자 지정 restrictSpeedChange 익스텐더를 작성했습니다. 여기에 : http://jsfiddle.net/kasheftin/Pn9r8/4/. 그리고 그것은 보통 관찰 할 수있는 것들에 실제로 적용됩니다.

ko.extenders.restrictChangeSpeed = function(target,timeout) { 
    var writeTimeoutInstance = null; 
    var currentValue = target(); 
    var updateValueAgain = false; 
    return ko.dependentObservable({ 
     read: target, 
     write: function(value) { 
      var updateValue = function(value) { 
       target(value); 
       if (!writeTimeoutInstance) { 
        writeTimeoutInstance = setTimeout(function() { 
         writeTimeoutInstance = null; 
         if (updateValueAgain) { 
          updateValueAgain = false; 
          updateValue(currentValue); 
         } 
        },timeout); 
       } 
      } 
      currentValue = value; 
      if (!writeTimeoutInstance) 
       updateValue(currentValue); 
      else 
       updateValueAgain = true; 
     } 
    }); 
} 

문제는 계산 된 관찰 가능 항목에서도 작동하도록하려는 것입니다. 스로틀 확장기에는 throttleEvaluation 변수가 있으며,이 변수는 dependentObservable.js evaluatePossiblyAsync 메소드에서 사용됩니다. 하지만 코어 녹아웃 파일에서 무엇이든 변경하고 싶지는 않습니다.

예를 들어, http://jsfiddle.net/kasheftin/Pn9r8/4/ 관찰 가능한 변수는 restrictChangeSpeedVar1이며 예상대로 작동합니다. 계산 된 변수는 restrictChangeSpeedComputedVar1입니다. 첫 번째처럼 작동하도록하려면 어떻게해야합니까?

답변

3

기존의 코드로가는 빠른 생각 : 당신이 관찰 계산이 아닌 쓰기를 다루고있는 경우 익스텐더에서

, 당신은, 당신의 익스텐더를 통과하고 가입했다는 관측을 돌아 볼 수 있었다 계산 된.

ko.extenders.restrictChangeSpeed = function(target, timeout) { 
    var writeTimeoutInstance = null; 
    var currentValue = target(); 
    var updateValueAgain = false; 
    var interceptor; 

    if (ko.isComputed(target) && !ko.isWriteableObservable(target)) { 
     interceptor = ko.observable().extend({ restrictChangeSpeed: timeout }); 
     target.subscribe(interceptor); 
     return interceptor; 
    } 
.... 

핵심은 "쓰기"논리를 통과하기 위해 뭔가가 필요하다는 것입니다. 정상적인 계산을 사용하면 "쓰기"코드를 거치지 않고 "읽기"논리 및 업데이트를 다시 평가할 수 있습니다. 여기

는 샘플입니다 : 당신은 당신의 익스텐더 이름의 철자가 잘못했다

self.restrictChangeSpeedComputedVar1 = ko.computed(this.var1).extend({restictChangeSpeed:1000}); 

(restict 대신 restrict), 내 머리를 긁어 만든 : 또한 http://jsfiddle.net/rniemeyer/GPbrR/

, 당신은 당신의 바이올린에 오타가 있었다 내가 알아 차릴 때까지 내가 추가 한 변경 사항을 테스트합니다.

내 변경 사항에 대한 유일한 흥미로운 점은 누군가가 계산에 쓸 수 있지만 현재 계산 된 값이 변경 될 때마다 항상 업데이트된다는 것이고 의도적으로 쓰기를 시도하는 이유가 표시되지 않는다는 것입니다.

+0

대단히 감사합니다! 실수로 사과 드리며, 내가 이걸 너무 꼼짝 못하게 한 이유가 될 수도 있습니다. – Kasheftin