2012-03-13 1 views
0

보기 코드 :녹아웃 바인딩을 잘못하고 있습니까?

<ul data-bind="foreach: BackColorOptions"> 
    <li data-bind="css: { selected: Selected }"> 
     <label> 
      <input type="radio" name="BackColorOption" 
       data-bind="value: Color, checked: $root.BackColor" /> 
     </label> 
    </li> 
</ul> 
@{ 
    var jsonModel = new System.Web.Script.Serialization. 
     JavaScriptSerializer().Serialize(Model); 
} 
<input type="hidden" id="JsonModel" value='@jsonModel' /> 

뷰 모델 코드 :

var initialData = $.parseJSON($('#JsonModel').val()); 

function BackColorOption(data, parent) { 
    var self = this; 
    self.parent = parent; 
    self.Text = ko.observable(data.Text); 
    self.Color = ko.computed(function() { 
     return '#' + self.Text().toLowerCase(); 
    }); 
    self.Selected = ko.computed(function() { 
     var backColor = self.parent.BackColor(); 
     if (backColor) { 
      return backColor.toLowerCase() == self.Color; 
     } 
     return false; 
    }); 
} 

function TestViewModel() { 
    var self = this; 

    self.BackColor = ko.observable(initialData.BackColor); 

    var mappedBackColorOptions = $.map(initialData.BackColorOptions, 
     function (item) { 
      return new BackColorOption(item, self); 
     } 
    ); 
    self.BackColorOptions = ko.observableArray(mappedBackColorOptions); 

} 

ko.applyBindings(new TestViewModel()); 

모델 코드 :

string BackColor { get; set; } 
SelectListItem[] BackColorOptions 
{ 
    get 
    { 
     return new[] 
     { 
      new SelectListItem{Text = "cc0000"}, 
      new SelectListItem{Text = "ff9900"}, 
      new SelectListItem{Text = "dddd33"}, 
      new SelectListItem{Text = "009900"}, 
      new SelectListItem{Text = "00cccc"}, 
      new SelectListItem{Text = "0066ff"}, 
      new SelectListItem{Text = "9900ff"}, 
      new SelectListItem{Text = "ff00ff"}, 
     }; 
    } 
} 

위의 IE에서 예상 작품으로 코드 (8) 및 크롬 (17)을 포함하지만 FF (10.0.2). 기본적으로 GitHub의 문제 라벨과 유사한 색상 선택기를 사용하려고합니다. 이 뷰는 클릭 할 수있는 라디오 버튼 집합을 렌더링하여 색상을 선택합니다. 라디오가 선택되면 부모 <li>selected css class을 추가합니다. CSS 클래스는 <li> 위에 체크 표시 아이콘을 표시합니다.

Firefox에서 선택한 CSS 클래스는 사용자가 각 라디오 버튼을 한 번 이상 확인한 후에 만 ​​적용됩니다. 디버깅을 한 결과, self.Color 계산 된 observable이 BackColorOption 클로저에서 평가되는 방식 때문이라고 밝혀졌습니다. 라디오가 처음 확인되기 전에 이 true로 평가됩니다. 그러나 검사 후 typeof(self.Color) == 'string'이 true로 평가됩니다.

typeof(self.Color) 동작은 Firebug와 Chrome의 js 디버거에 따라 동일합니다. 그러나 FF의 문제 때문에 BackColorOption 폐쇄에 관찰 계산 된 self.Selected에서이 라인이다 : self.Color 대신 문자열의 기능이 경우에도

return backColor.toLowerCase() == self.Color; 

크롬 & IE는 여전히 true를 돌려줍니다. 그러나 Firefox는 그렇지 않습니다. self.Color이 함수이면 false를 반환합니다. 따라서 CSS 클래스가 <li>에 추가되기 전에 각 라디오를 한 번 이상 확인해야하며 아이콘이 표시됩니다.

아직 녹아웃에 조금 익숙하고 예상 한 기능으로 viewmodel 속성을 적절하게 호출하지 않을 수 있습니다. 나는 () 괄호를 사용할 때와 생략 할 때를 조금 분명히 알지 못합니다. 또 다른 방법은 내가 self.Selected 작성해야합니다 self.Color에 따라 달라집니다 계산 관찰 (BackColorOption 폐쇄에) 계산? 나는 녹아웃 싸우는 것 같은

self.Selected = ko.computed(function() { 
    var backColor = self.parent.BackColor(); 
    var selfColor = self.Color; 
    if (typeof (selfColor) === 'function') 
     selfColor = self.Color(); 
    if (backColor) { 
     return backColor.toLowerCase() === selfColor; 
    } 
    return false; 
}); 

그러나,이 느낌 : 1

업데이트 나는 다음과 FF 10.0.2에서 작동이 얻을 수 있었다. "그냥 일하는"것이 아닌가요?

+0

는이를 입증하는 jsfiddle을 노크 수 : 당신의 BackColorOption 기능에 또한 http://jsfiddle.net/m2KQ2/

라인은 오타가? – madcapnmckay

+0

다음은 바이올린입니다. http://jsfiddle.net/JUKGh/2/ – danludwig

답변

2

KO의 value 바인딩은 라디오 버튼과 체크 박스에 적합하지 않습니다. 상황에 따라 value 라디오 버튼이 필요하므로 클릭하면 해당 값을 사용하여 TestViewModel.BackColor을 업데이트 할 수 있습니다.

일반적으로 라디오 버튼을 사용하면 value 속성이 html이 렌더링 된 후에 변경되지 않게 할 수 있습니다.

그래서 바인딩 (html 속성)을 사용하여 value 바인딩을 사용하여 HTML 템플릿을 변경했습니다. 이제 라디오 버튼의 value html 속성을 설정하는 중입니다. 그러면 checked 바인딩은 확인 된 라디오 버튼이 value 인 것과 일치하여 사용자의 TestViewModel.BackColor을 관찰 가능 상태로 유지합니다.

이 바이올린을 참조하십시오

:

self.Selected = ko.computed(function() { 
    var backColor = self.parent.BackColor(); 
    if (backColor) { 
     return backColor.toLowerCase() == self.Color; //<-- should be Color(); 
    } 
    return false; 
}); 
+0

감사합니다. 에릭, 예, 작동합니다. 가치 바인딩보다는 attr 바인딩을 사용하여 값을 바인딩하는 것은 나에게 발생하지 않았다. 당신 말이 맞아요, 나는 라디오 버튼 값을 변경하고 싶지 않아요. 나는 당신의 바이올린이 self.Color()를 함수로 호출하고 있음을 알았고 그에 따라 코드를 업데이트했습니다. – danludwig