2012-10-24 6 views
3

구독 함수 내부에서 관측 가능한 값을 어떻게 바꿀 수 있습니까? 구독 함수 내에서 관찰 가능 값을 어떻게 변경할 수 있습니까?

JS 모델 예를 들어

:

function Model(){ 
    self = this; 
    self.Test = ko.observable(2); 
    self.Test.subscribe(function(){ 
     if (/**Some bool expression**/) { 
     self.Test(2); 
     } 
    }); 
} 

HTML 기본적 초 전파 입력에 의한

<input type="radio" value="1" data-bind="checked:Test" /> 
<input type="radio" value="2" data-bind="checked:Test" /> 
<input type="radio" value="3" data-bind="checked:Test" /> 

체크한다. 첫 번째 라디오를 클릭하면 첫 번째와 두 번째 라디오가 모두 선택됩니다.

enter image description here

업데이트 : 내가 jQuery를 녹아웃를 모두 포함 할 때 그것은이 발생합니다. jquery를 제거하면 모두 Ok입니다. 하지만 테스트 페이지 일뿐입니다. 실제 프로젝트에서는 jQuery를 일부 장소에서 사용해야하며,이 경우 제거 할 수 없습니다.

Sample. 테스트 페이지의 출처 : 구독/출판 뒤에

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <script type="text/javascript" src="knockout-2.1.0.js"></script> 
     <script type="text/javascript" src="jquery-1.6.4.js"></script> 
     <script type="text/javascript"> 
      function Model(){ 
       self = this; 
       self.Test = ko.observable(2); 
       self.Test.subscribe(function(){ 
        if (true) { 
        self.Test(2); 
        } 
       }); 
      } 
     </script> 
    </head> 
<body> 
    <input type="radio" value="1" data-bind="checked:Test" /> 
    <input type="radio" value="2" data-bind="checked:Test" /> 
    <input type="radio" value="3" data-bind="checked:Test" /> 
</body> 
<script type='text/javascript'> 
    ko.applyBindings(new Model()); 
</script> 
</html> 
+1

아마도이 피들을 기반으로 재현 할 수 있습니다. http://jsfiddle.net/rniemeyer/2uCAF/? 바인딩으로 인해 첫 번째와 두 번째 라디오를 모두 선택할 수 없기 때문에 다른 문제가 발생할 수 있다고 생각합니다. 또한 입력 내용에 공통된 'name'속성을 지정해야합니다. KO는 이들을 계속 그룹화하여 유지합니다. –

+0

예, 이름 특성을 추가하십시오. http://www.w3.org/TR/html401/interact/forms.html#radio – mg1075

답변

7

UPDATE (2015-02-27) : Knockout 3.1.0부터 Knockout에는 click 이벤트에 대한 "대안"코드가 포함되어 있지 않으므로 문제의 예제를 처리 할 때 문제가 없어야합니다. jQuery를 포함한다 http://jsfiddle.net/9S96U/3/


, 녹아웃 라디오 버튼에 응답하는 데 사용되는 click 이벤트를 포함하여 이벤트를 처리하는 데 사용합니다. 여기에는 클릭 핸들러가 올바른 의 라디오 버튼 확인 상태를 확인하는 데 필요한 "해결 방법"코드가 포함되어 있지만이 코드는 중간에 확인 된 값을 다시 설정하려고 시도하는 코드를 방해하는 것으로 보입니다.

해결책은 setTimeout을 사용하여 값을 업데이트하는 것입니다. 그런 식으로 클릭 핸들러가 완료된 후에 발생합니다.

function Model(){ 
    var self = this; 
    self.Test = ko.observable(2); 
    self.Test.subscribe(function(){ 
     setTimeout(function() { 
      self.Test(2); 
     }); 
    }); 
} 

예 :

http://jsfiddle.net/9S96U/1/ 또한 그렇게 varself = this 전에를 포함하면 window.self 덮어 쓰기하지 않는 것이 필요합니다.

0

아이디어는 하나의 관찰자가 자신의 테스트를 여러 가입자에게 결과를 보낼 수 있다는 것입니다.

아직 knockout.js를 사용하지는 않았지만 위임/비동기 흐름/약속/등으로 많은 작업을 해왔습니다. 대부분 특별한 경우를 위해 간단한 구현을 사용합니다.

귀하의 목표는 테스트를 한 번 실행 한 컨트롤러 (지금 가지고있는 컨트롤러)를 가지고 각 컨트롤러를 반복하면서 올바른 하나 (i - 1)가 선택되었는지 확인하는 것입니다. 선택을 취소했습니다 ...

... 또는 더 전통적인 게시자/구독자 방식 인 경우 하나의 게시자 (모든 라디오 컨트롤의 부모 요소 일 수있는 fieldset)가 입력 중 하나 변경하고 값을 구독하는 각 사용자에게 각자에게 알리고 자신의 테스트를 보냅니다.

var subscribers = []; // array of input "Model" callbacks 
         // (ie: tests to determine whether they're off or on) 

parentElement.listen("click", function (e) { 
     var self = this, 
      selectedRadio = e.target, 
      val = selectedRadio.value; 

     subscribers.forEach(function (notify) { notify(val); }); 
}); 

, 당신은 의존성 주입을 사용할 수있는 현재의 상황을 처리하려면 : 의사 발언에서

은 당신도 캐시

new Model(value); 

또는

new Model(subscription_test_for_element); 

는 예상 테스트 값 또는 각 개별 기능 내부에서 입력 특정 테스트/성공/실패 로직을 캐시하는 위치 tance ...

... 또는 각 입력에 대해 하드 코딩 된 논리를 처리하기 위해 더 큰 컨트롤러 (권장하지 않음)를 만듭니다. 물론

더 많은 별 도움말 정확하게 에 따라 주어질 수있는 것을 모델 당신이 그것을가 일어나고 있다면 왜 건설에 가입을 하드 코딩하고, 인스턴스화하고 어떻게입니다 제네릭 모델 등이 될 수 있습니다.

관련 문제