2012-07-31 4 views
0

데이터 테이블에 포함 된 관찰 가능 어레이에 요소를 프로그래밍 방식으로 추가하는 데 문제가 있습니다.Knockout.js 배열에 새 항목 추가

테이블의 각 행에는 영향을 미치고 싶은 다른 배열이 있습니다.

<div class='liveExample'>  
<h2>Cases</h2> 
<div id='contactsList'> 
    <table class='contactsEditor'> 
     <tr> 
      <th>Case Number</th> 
      <th>Stage</th> 
      <th>Users</th> 
      <th>Ids</th> 
     </tr> 
     <tbody data-bind="foreach: appearances "> 
      <tr> 
       <td> 
        <input data-bind='value: caseNumber' /> 
       </td> 
       <td><input data-bind='value: caseStage' /></td> 
       <td> 
        <ul data-bind="foreach: subjects"> 
         <li style="list-style-type:none;"><label data-bind="text: Name"/></li>  
        </ul> 
       </td> 
       <td> 
        <table> 
         <tbody data-bind="foreach: ids"> 
          <tr> 
           <td><input data-bind='value: $data' /></td> 
           <td><a href='#' data-bind='click: $root.removeId'>Delete</a></td> 
          </tr> 
         </tbody> 
        </table> 
        <a href='#' data-bind='click: $root.addId'>Add number</a> 
       </td> 
      </tr> 
     </tbody> 
    </table> 
</div>  
<p> 
    <button data-bind='click: save, enable:appearances().length > 0'>Save to JSON</button> 
</p>  
<textarea data-bind='value: lastSavedJson' rows='5' cols='60' disabled='disabled'> </textarea>  

데이터와 자바 스크립트는 다음과 같습니다 :

HTML은 다음과 같습니다

enter code here 
var initialData = [{ 
"Number": "12000009", 
"Stage": "Inital", 
"Subjects": [{ 
    "Name": "Andrew McAdam"}, 
{ 
    "Name": "Patrick Brown"}], 
"Ids": [1]}, 
{ 
"Number": "12000010", 
"Stage": "Inital", 
"Subjects": [{ 
    "Name": "John Smith"}], 
"Ids": [2, 3]}, 
{ 
"Number": "12000011", 
"Stage": "Inital", 
"Subjects": [{ 
    "Name": "James Bonner"}], 
"Ids": [4]}, 
{ 
"Number": "12000012", 
"Stage": "Processed", 
"Subjects": [{ 
    "Name": "Henrik Dalgleish"}], 
"Ids": [5]}] 

var AppearancesModel = function(appearances) { 
var self = this; 
self.appearances = ko.observableArray(ko.utils.arrayMap(appearances, function(appearance) { 
    return { 
     caseNumber: appearance.Number, 
     caseStage: appearance.Stage, 
     subjects: ko.observableArray(appearance.Subjects), 
     ids: ko.observableArray(appearance.Ids) 
    }; 
})); 

self.addId = function(appearance) { 
    appearance.ids.push(""); 
}; 

self.removeId = function(id) { 
    $.each(self.appearances(), function() { 
     this.ids.remove(id) 
    }) 
}; 

self.save = function() { 
    self.lastSavedJson(JSON.stringify(ko.toJS(self.appearances), null, 2)); 
}; 

self.lastSavedJson = ko.observable("") 
} 

ko.applyBindings(new AppearancesModel(initialData));​ 

내가 가진 문제는 그가 추가 버튼을 클릭 한 후 배열에 값을 입력하면 빈 문자열 (새 배열 요소를 만들 때 값)이됩니다.

나는 값이 있기 전에 배열에 새 항목을 추가한다고 생각하지만 새 값에 바인딩 될 것이라고 생각 했으므로 Save 함수를 실행하면 새로운 값이 반영됩니다. .

위의 JsFiddle는 http://jsfiddle.net/amcgoldrick/3h9GZ/

감사

앤디

+0

@ Mark-Robinson의 조언에 따라 원래 ID를 매핑하기 위해 다음을 추가했습니다. ko.observableArray (ko.utils.arrayMap (appearance.Ids, function (id) {return ko.observable (id) }))'그리고 원래의 id가 표시됩니다. 지금 가지고있는 문제는 'appearance.ids.push ({id : ko.observable (""}));' id 속성이있는 객체를 정수 배열에 추가합니다. – AndyMcG

답변

3

이 때문에 바인딩은 단 하나의 방법은 관찰되지 않습니다 당신의 idsobservableArray에 추가하는 값이다. observableArray 내부의 값을 업데이트하려면 observableArray 내부의 요소를 관찰 할 수 있어야합니다.

그래서 대신 :

self.addId = function(appearance) { 
    appearance.ids.push(""); 
}; 

당신은 할 것이다 :

self.addId = function(appearance) { 
    appearance.ids.push({id: ko.observable("")}); 
}; 

는 작업, 예를 들어 http://jsfiddle.net/5wKjk/3/를 참조하십시오. (필자는 기존의 ID를 매핑하는 코드를 추가하지 않았기 때문에 관련 원칙을 보여주고 싶었고 시간이 없었습니다.)

+0

훌륭해, 조금 더 가까이 가는데 도움이된다. – AndyMcG

+0

'appearance.ids.push ({id : ko.observable ("")});를 사용하면 속성'id'와 값'' "'을 가진 객체가 추가됩니다. 간단한 정수를 추가하는 방법을 연습 할 수 없습니다. – AndyMcG

+0

바이올린을 보았습니까? 마크 업에서 바인딩을 변경하여 'id'속성을 처리했습니다. 또한 입력란에 값을 바인딩하려는 경우 텍스트 상자에 무언가를 입력하면 녹아웃은 항상 문자열을 모델에 다시 작성합니다. 따라서, 나는 당신의 값이 정수인지 또는 문자열인지에 관심을 갖지 않을 것이다. 결국 JavaScript에서는 1 == "1"입니다. –