2012-12-30 1 views
2

데이터의 각 행에 selectall toggle 확인란과 checkbox가 있습니다.Ajax 호출 성공 후 viewmodel을 ui에 바인딩합니다. 녹아웃

이제 서버에서 반환 된 데이터에는 관찰 할 수없는 데이터가 isSelected입니다. 각 행에 대해 'isSelected'관찰 가능을 추가했습니다. 그러나 관찰 가능하지 않은 isSelected은 각 행의 체크 박스에 바인딩됩니다. 여기

는 뷰 모델입니다 :

var folderViewModel = function() { 
    var self = this; 
    self.Folders = ['Inbox', 'Archive', 'Sent', 'Spam']; 
    self.SelectedFolder = ko.observable(); 
    self.Mails = ko.observableArray([]); 
    self.SelectedMail = ko.observable(); 
    self.SelectAll = ko.observable(false); 

    self.navigate = function (folder) { 
     self.SelectedFolder(folder); 
     //$.get('/Api/MailBox', { folder: folder }, self.Mails); 

     $.ajax({ 
      url: "/Api/Mailbox", 
      data: { folder: folder }, 
      success: function (data) { 
       ko.mapping.fromJS(data, {}, self.Mails); 
       ko.utils.arrayForEach(self.Mails(), function (mail) { 
        mail.isSelected = ko.observable(true); 
        mail.isSelected.subscribe(function (myvalue) { 
         console.log(myvalue); 
        }); 
       }); 
       console.log(ko.toJSON(self.Mails())); 
      }, 
      statusCode: { 
       404: function() { 
        alert("No Mail"); 
       } 
      } 
     }); 

     //ko.mapping.fromJS(data, {}, self.Mails); 
     //console.log(ko.toJSON(self.Mails)); 
    }; 

    self.SelectAll.subscribe(function (newValue) { 
     ko.utils.arrayForEach(self.Mails(), function (mail) { 
      console.log(mail.isSelected()); 
      mail.isSelected(newValue); 

     }); 
     console.log(newValue); 
    }, self); 

    this.navigate("Inbox"); 
}; 
ko.applyBindings(new folderViewModel()); 

그리고 여기에 바인딩입니다.

<table class="table table-bordered table-striped table-condensed table-hover"> 
<thead> 
    <tr> 
     <th> 
      <input type="checkbox" data-bind="checked: SelectAll"/> 
      @*<input type="checkbox" />*@ 
     </th> 
     <th> 
      From 
     </th> 
     <th> 
      To 
     </th> 
     <th> 
      Subject 
     </th> 
     <th> 
      Date 
     </th> 
    </tr> 
</thead> 
<tbody data-bind="foreach:Mails"> 
    <tr data-bind="click:$root.navigateToMail"> 
     <td style="width: 15px"> 
      <input type="checkbox" data-bind="checked: $root.isSelected"> 
      @*<input type="checkbox">*@ 
     </td> 
     <td data-bind="text: From"> 
     </td> 
     <td data-bind="text: To"> 
     </td> 
     <td data-bind="text: Subject"> 
     </td> 
     <td data-bind="text: MailDate"> 
     </td> 
    </tr> 
</tbody> 

체크 박스 <input type="checkbox" data-bind="checked: $root.isSelected">

mails.isSelected=ko.obsevable(true)에서 아약스 데이터 바인딩지고 있지 않습니다. 무엇이 문제일까요?

답변

4

먼저, kuddos는 learn.knockoutjs.com 예제를 사용하여 놀라운 리소스를 제공합니다.

오류는 KnockoutJS의 공통적 인 함정입니다. 바인딩 된 관측 가능 항목을 업데이트하지 않고 모델을 수정하고 있습니다. 다음 줄을 참조하십시오 -

당신이 볼 경우
ko.mapping.fromJS(data, {}, self.Mails); 
ko.utils.arrayForEach(self.Mails(), function (mail) { ... }); 

, 먼저 메일에 대한 모델을 만든 다음 여분의 관찰을 추가하고 있습니다. 이 관찰 내용은 어떤 맥락에서 첨부되어야 하는가? 각 메일의 값을 업데이트하지 않으면 mail.isSelected이 메일 개체에 추가되지 않습니다.

이 문제를 해결하는 방법에는 두 가지가 있습니다. 첫 번째, 당신은 foreach는 배열의 메일 모델을 업데이트 :

ko.utils.arrayForEach(self.Mails(), function (mail, index) { 
    // Add up the isSelected observable 
    self.Mails()[index] = mail; 
}); 

이것은 당신이 here을 읽을 수있는 관찰 어레이의 성능 잡았다가 있습니다. 기본적으로 임시 배열을 만들고 매번 Mails()을 호출하는 것보다 관찰 가능 어레이 전체를 업데이트하려고합니다.

은 다른 방법은 매우 간단합니다 : 당신은 어떻게 메일 모델 작성의 순서 교체 :

ko.utils.arrayForEach(self.Mails(), function (mail) { ... }); 
ko.mapping.fromJS(data, {}, self.Mails); 

FIRST를, 당신은 "당신의 관찰 객체 그리고 당신이 당신의 ViewModel에 말하고있다 데이터에 부착된다 이봐! 우리는 그것을 저장하는 새로운 모델을 가지고있다.이 속성은 data에서 관찰 할 수있다. 선택했다. 방금 추가했는데, 묶어 버릴까? " 에 isSelected이 메일 대신 뷰 모델에 바인더 제본 받고 같이 말했다되고 그건

은 HTML의 속성은,이 종류의 선택 SelectAll (종류의) 작업 된 이유를했다 checked: isSelected하지 checked: $root.isSelected입니다 모델.http://jsfiddle.net/jjperezaguinaga/VTuHA/ : 그것을해야

// In any row inside your data 
<td data-bind="text: ko.toJSON($data)">DEBUG DATA</td> 

, 당신은 당신의 코드가 여기서 일뿐만 아니라 모든로서의 솔루션을 볼 수 있습니다 당신은이 편리한 문 디버깅을 알아낼했다 할 수있다. 몇 가지 예제 데이터를 추가하여 (JsFiddle의 /echo/json/ 기능 사용) 일부 항목과 제거한 마지막 코드로 디버깅하는 데 사용 된 추가 열을 제거했습니다. 이 마지막 열에서 체크 박스를 클릭 할 때마다 isSelected 값이 업데이트되는 것을 볼 수 있습니다.

+0

훌륭한 답변이지만 한 부분을 설명하는 데주의하십시오. 실제로 데이터에 관찰 가능한 속성을 연결 한 다음이를 녹아웃 매핑으로 매핑했음을 강조합니다. 죄송합니다 멍청한되고 있지만 둘 다 같은 arent? 처음에는 관찰 할 수있는 배열을 만들고 observable 속성을 첨부하면 (분명히 내가 한 일이지만 작동하지 않았다). 여기 내 잘못이 무엇인지 설명해 주시겠습니까? – Joy

+0

아무런 문제가 없으며 멍청한 질문이 있습니다. 한가지는 ViewModel입니다. (전체 함수 객체를 생각해보십시오. 하나는'$ root' 태그로 액세스하고 다른 하나는 메일 모델입니다. 당신의 ViewModel은 Mail Models의 콜렉션 (ko.observableArray)을 가지고 있는데, 바인드해야 할 때 ViewModel ('$ root.isSelected' 작업)에'isSelected'를 바인딩하는 것이 문제였습니다 각 메일 모델과 적절한 범위에 대한 설명입니다. – jjperezaguinaga

+0

이것은 유명한 Javascript의'this' 단어와 관련이 있습니다. foreach의 Mail 객체에 ko.observable을 추가했을 때 컨텍스트는 무엇입니까? ViewModel이었습니다. Btw, Model은 "클래스"를 나타내는 Backbone에서 복사 한 구문 일 뿐이며 KnockoutJS에서는 실제로 사용되지 않습니다.이 단어를 사용하면 당신의 메일은 sp 특정 클래스에서 ecific 개체와 당신을 혼란스럽게하지 마십시오 :) – jjperezaguinaga

0

mail 항목에 isSelected이 추가되지 않았으며뷰 모델에 추가되지 않았습니다. 그렇다면 당신은해야 바인딩 :

<input type="checkbox" data-bind="checked: isSelected"> 

참고 : 나는 또한 또한 문제가 발생할 것입니다 root 뷰 모델에서 사용할 수있는 navigateToMail 방법을 볼 수 없습니다.

+0

나는 그것을 실제로했다. 그러나 그것은 그것이라고 말합니다 .Selected는 정의되지 않았습니다. – Joy

관련 문제