2017-03-15 1 views
1

나는 여러 번 이미 물었다는 것을 알고 있지만 그 중 아무도 내 질문에 대답했다. 다음과 같습니다. JSON에서 Javascript로 데이터를 가져와 2 차원 배열로 만듭니다. 사이트를로드 할 때 원하는 테이블이 표시됩니다. 이제 테스트를 위해 버튼을 클릭하면 배열의 값 하나가 업데이트되고 콘솔에 배열이 기록되어 변경된 배열을 볼 수 있습니다. 문제는 테이블에 변경 사항이 표시되지 않는다는 것입니다. 방금 ​​배열에 값을 추가하면 테이블에 값이 표시됩니다. 내가 뭘 잘못하고 있니?녹아웃 JS 배열을 변경하면 업데이 트되지 않습니다

HTML :

<table id="sortsTable"> 
    <tbody data-bind="foreach: sorts"> 
    <tr> 
    <td data-bind="text: $data.name"></td> 
    <td data-bind="text: $data.ingName"></td> 
    </tr> 
    </tbody> 
</table> 
<button data-bind="click: addPerson">Add</button> 

JS :

var sorts = ko.observableArray([]); 

$(function() { 
var request = new XMLHttpRequest(); 
var formData = new FormData(); 
var responseElements = []; 
request.open("POST", "scripts.php", true); 
formData.append("action", "getSorts"); 
request.onreadystatechange = function() { 
    if (request.readyState == 4 && request.status == 200) { 
     responseElements = JSON.parse(request.responseText); 
     sorts = convertList(responseElements); 
     ko.applyBindings(new AppViewModel(sorts)); 
    } 
} 
request.send(formData); 

}); 

function convertList(response) { //just the function to convert the json object to a more useful array 
    var names = []; 
    var ingredients = []; 
    var sorts = []; 
    for (var index = 0; index < response.length; index++) { 
     var name = response[index]['name']; 
     var ing = response[index]['ingName']; 
     if (names.indexOf(name) == -1) { 
      names.push(name); 
     } 
     if (ingredients.indexOf(ing) == -1) { 
      var nameIndex = names.indexOf(name); 
      if (ingredients[nameIndex] == undefined) { 
       ingredients[nameIndex] = ing; 
      } else { 
       ingredients[nameIndex] = ingredients[nameIndex] + ", " + ing; 
      } 
     } 
    } 
    for (var i = 0; i < names.length; i++) { 
     sorts[i] = {}; 
     sorts[i]['name'] = names[i]; 
     sorts[i]['ingName'] = ingredients[i]; 
    } 
    return sorts; 
} 

function AppViewModel(data) { 
    var self = this; 
    self.sorts = data; 
    self.addPerson = function() { 
     console.log("click"); 
     self.sorts[0]["name"] = "test"; //doesn't update table 
     //self.sorts.push({name: "qwer", ingName: "we"}); //works like expected 
     console.log(self.sorts); 
    }; 
} 

감사합니다.

+0

이 아마 무슨 일이 : 당신은 단순히 그냥 관찰 녹아웃을 덮어 쓸 것 같이 속성에 할당 할 수 없습니다 및 분실됩니다 그러나 참고, 대신 당신은 전화 업데이트와 함께 관찰 필요 knockout.js가 배열에 대한 변경 사항을 모니터링하지만 변수에 대한 업데이트는 모니터링하지 않습니다. 새 요소를 추가 할 때 배열의 내용을 변경하지만 요소를 업데이트하면 변수가 변경되지만 배열은 이미 가지고있는 변수와 동일한 포인터를 모두 유지할 수 있습니다. 녹아웃에서 새로 고침 이벤트를 실행해야 할 가능성이 높습니다. – tswei

+0

네, 관측 대상을 사용하고있는 것처럼 보이지 않습니까? 정말 녹아웃을 사용하여 무의미 해집니다. 나는 당신이 일부 녹아웃 튜토리얼을 읽을 것을 제안한다. –

+0

@JasonSpake 나는 관찰 가능한 배열을 사용하고있다. 코드의 시작 부분을 살펴보십시오. 내가 제대로하지 않니? – jukisu

답변

1

관찰 가능한 배열 항목 만이 추가되는 모니터가 아닌 상품 자체, 당신이 항목을의에 추가 관찰 배열을 받고 있기 때문에 그렇게

self.sorts.push({name: "qwer", ingName: "we"}); //works like expected 

작동하지만

self.sorts[0]["name"] = "test"; //doesn't update table 
관찰 가능한 배열은 내부에있는 항목이 변경되었음을 알 수 없기 때문에

이 작동하지 않습니다. 이 작업을하려면 배열의 항목 속성을 관찰 할 수 있어야합니다.

에 convertList 스위치에서

:

for (var i = 0; i < names.length; i++) { 
    sorts[i] = {}; 
    sorts[i]['name'] = ko.observable(names[i]); 
    sorts[i]['ingName'] = ko.observable(ingredients[i]); 
} 

그리고 그들과 같이 관찰 setter 메소드 호출하여 설정해야합니다 : 여담으로 또한

self.addPerson = function() { 
    console.log("click"); 
    self.sorts[0]["name"]("test"); 
    ... 

, 당신은 여기에 몇 가지 다른 문제를 갖고있는 것 같다 . 첫 번째 줄에는 정렬을 관찰 가능한 배열로 정의하지만 convertList의 반환 값으로 덮어 씁니다.이 배열은 관측 가능한 배열이 아닌 일반 배열입니다.

sorts = convertList(responseElements); 
ko.applyBindings(new AppViewModel(sorts)); 

나는 첫 번째 줄을 제거하고

function convertList(response) { //just the function to convert the json object to a more useful array 
    var names = []; 
    var ingredients = []; 
    var sorts = ko.observableArray([]); 
    ... 
+0

변환 목록에서 : for (var i = 0; i < names.length; i ++) { 정렬 [i] = {}; 정렬 [i] [ '이름'] = ko.observable (이름 [i]); 정렬 [i] [ 'ingName'] = ko.observable (ingredients [i]); } 관측 가능한 배열을 초기화 할 때 인수가 값이 아닌 배열이어야하기 때문에 ... – jukisu

+0

우리는 관측 가능한 배열을 초기화하지 않습니다. 우리는 관측 가능을 초기화합니다. – user3432422

+0

음, 맞아. 내가 추측하는 것을 보지 못했다. 배열을 변경했는데 어떤 이유로 배열이 비어 있습니다. 그래서 아무것도 출력하지 않습니다. – jukisu

2

문제는 당신이 바인딩 할 때이 것을하는 관찰 배열로 종류를 만들 것입니다 :

<td data-bind="text: $data.name"></td> 

$data.name이 관찰되지 않습니다, 그것의 여기에 생성 된 객체의 간단한 속성 :

sorts[i]['name'] = names[i]; 

Knockout은 이와 같은 속성을 매우 행복하게 바인딩하고 표시하지만, 모든 업데이트는 녹아웃에 표시되지 않습니다. 대신에,뿐만 아니라 당신의 observableArray, 당신은 또한 당신이 관찰뿐만 아니라 업데이트 할 수있는 기능을 원하는 개별 속성을 확인해야합니다 : 당신이 그것을 업데이트 할 때

sorts[i]['name'] = ko.observable(names[i]); 

그런 다음, 녹아웃의 변화를 볼 수 있습니다.

self.sorts[0]["name"]("test");