2013-12-09 2 views
2

넉 아웃과 함께 트위터 부트 스트랩 버튼 그룹을 사용하고 있습니다. 나는 아주 단순한 것을 간과하고있는 것처럼 느껴지지만,이 인스턴스에서는 checked 바인딩을 사용할 수 없었습니다.넉 아웃 체크 바인딩이 작동하지 않음

나는 여기에서 문제를 재현하는 jsFiddle를 가지고있다 : http://jsfiddle.net/n5SBa/. 여기

는 바이올린의 코드입니다 : 예에서

<div class="form-group"> 
    <div class="btn-group" data-toggle="buttons"> 
     <label class="btn btn-primary" data-bind="click: ClickScore.bind($data, '0'), css: { active: Score() == '0' }"> 
      <input type="radio" name="score" value="0" data-bind="checked: Score" /> 0 
     </label> 
     <label class="btn btn-primary" data-bind="click: ClickScore.bind($data, '1'), css: { active: Score() == '1' }"> 
      <input type="radio" name="score" value="1" data-bind="checked: Score" /> 1 
     </label> 
     <label class="btn btn-primary" data-bind="click: ClickScore.bind($data, '2'), css: { active: Score() == '2' }"> 
      <input type="radio" name="score" value="2" data-bind="checked: Score" /> 2 
     </label> 
     <label class="btn btn-primary" data-bind="click: ClickScore.bind($data, '3'), css: { active: Score() == '3' }"> 
      <input type="radio" name="score" value="3" data-bind="checked: Score" /> 3 
     </label> 
     <label class="btn btn-primary" data-bind="click: ClickScore.bind($data, '4'), css: { active: Score() == '4' }"> 
      <input type="radio" name="score" value="4" data-bind="checked: Score" /> 4 
     </label> 
     <label class="btn btn-primary" data-bind="click: ClickScore.bind($data, '5'), css: { active: Score() == '5' }"> 
      <input type="radio" name="score" value="5" data-bind="checked: Score" /> 5 
     </label> 
    </div> 
</div> 

<pre data-bind="text: ko.toJSON($data, null, 2)"></pre> 

자바 스크립트

function SurveyViewModel() { 
    var self = this; 

    self.Score = ko.observable(); 

    //Events 
    self.ClickScore = function (score) { 
     self.Score(score); 
    }; 

    //Computations 
    self.RecommendationLabel = ko.computed(function() { 
     if (self.Score() < 8) { 
      return "Some question?"; 
     } else { 
      return "Some other question?"; 
     } 
    }); 

    self.DOMSelectedScore = ko.computed(function() { 
     if ($('input[name=score]:checked').val()) { 
      return $('input[name=score]:checked').val(); 
     } else { 
      return 'no value!'; 
     } 
    }); 
}; 

var surveyViewModel = new SurveyViewModel(); 

ko.applyBindings(surveyViewModel); 

HTML, 나는 실제 라디오 버튼을 얻을 수 없습니다 해요 내 양식에서 제대로 제출할 수 있도록 DOM에서 선택하십시오.

답변

8

체크 상자의 값은 문자열 ("0", "1" 등)이지만 관찰 가능 값은 숫자로 설정합니다. checked 바인딩은 비교할 때 완전 항등을 사용하며 숫자 1은 문자열 "1"과 같지 않습니다.

당신은 문자열로 관찰의 값을 설정하여이 문제를 해결할 수 있습니다

data-bind="click: ClickScore.bind($data, '1')" 

http://jsfiddle.net/mbest/n5SBa/2/

+0

실제로 문자열에 전달할 코드 설정이 있습니다. 내 부분에 오타가있었습니다. (DOM 선택 값은 아직 정의되지 않았습니다.) –

+0

콘솔을 열고'$ ('input [name = score] : checked')'를 실행하고 올바른 항목을 반환합니다. –

+0

답변이 도움이 되었기 때문에 +1을드립니다. 그러나 나는 문제가 내 생각보다 조금 복잡하게 보였기 때문에 내 대답을 추가하고있다. –

3

는 결코 계산하지됩니다, 그래서 다른 관찰을 참조하지 않습니다 관찰 계산 된 DOMSelectedScore.

self.DOMSelectedScore = ko.computed(function() { 
    self.Score(); // subscribe to Score, even if we don't use it. 
    var val = $('input[name=score]:checked').val(); 
    return val || 'no value!'; 
}); 

DOM이 함수가 반환 될 때까지 업데이트되지 않으므로 값이 한 번의 클릭에 비해 뒤떨어져있는 것으로 보입니다. 이 문제를 해결하려면, 우리는 DOM이 업데이트 될 때까지 연기해야 ​​

self.DOMSelectedScore = ko.computed(function() { 
    self.Score(); // subscribe to Score, even if we don't use it. 
    var val = $('input[name=score]:checked').val(); 
    return val || 'no value!'; 
}).extend({throttle:1}); // Wait for the DOM update to complete 

http://jsfiddle.net/n5SBa/5/


가 녹아웃 숫자의 바인딩을 단순화하기 위해, 당신은 관찰 가능한을위한 확장 방법을 정의 할 수 있습니다 :

ko.observable.fn.asString = function() { 
    var source = this; 
    if (!source._asString) { 
     source._asString = ko.computed({ 
      read: function() { 
       return String(source()); 
      }, 
      write: function (newValue) { 
       source(Number(newValue)); 
      } 
     }); 
    } 
    return source._asString; 
}; 

그리고

<input type="radio" name="score" value="2" data-bind="checked: Score.asString()"/> 
+0

내가 조금 당황한 이유는 jsFiddle이 문자열을 전달하지 않고도 (다른 답변과 같이해야한다고 말합니다.) 어떻게 작동하는지입니다. –

+0

트위터 부트 스트랩과 관련이있는 것 같습니다. 해당 js 파일을 제거하면 일반 번호로 작업하지 않습니다. –

+1

맞습니다.부트 스트랩은 바인딩과 독립적으로 체크 박스의'checked' 속성을 설정합니다. –

관련 문제