2014-02-15 2 views
9

잘 작동하는 observablearray가 있지만 UI가 업데이트되지 않습니다. 나는이 유형의 문제를 겪고있는 많은 사람들을 읽었지 만 나는 그것을 보지 못하고있다. 녹아웃 ObservableArray가 업데이트되지 않음 Foreach

는 그래서 HTML은

  <tbody data-bind="foreach: tweets"> 
      <tr> 
       <td> 
        <span data-bind="visible: created_at" class="label label-success">Yup</span> 
       </td> 
       <td><p><b data-bind="text: screen_name"></b></p></td> 
       <td><p><b data-bind="text: id"></b></p></td> 
       <td><p data-bind="text: text"></p></td> 
       <td><p data-bind="text: created_at"></p></td> 
      </tr> 
      </tbody> 

입니다 그리고 자바 스크립트 API를 호출하고 그것에서 배열을 구축하는 기능입니다.

<script type="text/javascript"> 
     function TweetsViewModel() { 
      var self = this; 
      self.tasksURI = 'http://localhost:8000/api/v1/tweet/'; 
      self.tweets = ko.observableArray(); 

      self.ajax = function(uri, method, data) { 
       var request = { 
        url: uri, 
        type: method, 
        contentType: "application/json", 
        Accept: "application/json", 
        cache: false, 
        dataType: 'json', 
        data: JSON.stringify(data) 
       }; 
       return $.ajax(request); 
      } 

      self.ajax(self.tasksURI, 'GET').done(function(data) { 
       for (var i = 0; i < data.objects.length; i++) { 
        var tweet = this; 
        tweet.created_at = ko.observable(data.objects[i].created_at) 
        tweet.text = ko.observable(data.objects[i].text) 
        tweet.id = ko.observable(data.objects[i].id) 
        tweet.screen_name = ko.observable(data.objects[i].twitteruser.screen_name) 
        self.tweets.push(tweet) 
       } 
      }); 
      setTimeout(TweetsViewModel, 10000) 
     } 
     ko.applyBindings(new TweetsViewModel()); 
    </script> 

단지 테스트 목적으로 setTimeout을 사용하여 API 호출을 다시 실행하고 배열을 업데이트합니다. 배열은 제대로 업데이트되지만 UI는 업데이트되지 않습니다. 나는 나의 무지를 사과한다. (오랜 기간 동안 백엔드 개발자였으며, Javascript에서 10 년 만에 처음 실행되었다.) 도움이 많이 감사!

답변

3

observableArray를 업데이트하지 않는 것이 문제입니다.

다시 시작하려면 생성자를 다시 호출해야하지만 this 참조는 생각하는 대상을 가리키고 있지 않습니다. TweetsViewModel 생성자를 다시 호출하면 (setTimeout 호출에서) this 참조는 window 개체를 가리 킵니다. 당신이 바로 그 물체를 가리 키도록 this 참조 수 (기능이 가지고있는 apply 방법을 사용하여 가능하다, 그러나 그 점 옆의) 당신이 설정 될 것입니다 때문에, 당신은 여전히 ​​observableArray를 업데이트되지 않을 경우에도

self.tweets = ko.observableArray(); 

모든 구독, 예를 들면 라인에 새로운 observableArray에 self.tweets 변수 UI DOM 요소는 변수가 변경되었음을 알지 못하기 때문에 이전 observableArray에 여전히 가입됩니다. 또한,

self.reloadData = function(){ 
    self.ajax(self.tasksURI, 'GET').done(function(data) { 
     for (var i = 0; i < data.objects.length; i++) { 
      // Important: Create a new tweet object instead of using 'this' here. 
      var tweet = {}; 
      tweet.created_at = ko.observable(data.objects[i].created_at) 
      tweet.text = ko.observable(data.objects[i].text) 
      tweet.id = ko.observable(data.objects[i].id) 
      tweet.screen_name = ko.observable(data.objects[i].twitteruser.screen_name) 
      self.tweets.push(tweet) 
     } 
    }); 
} 
setTimeout(self.reloadData, 10000); 

그것을 분명히 (이 항상 observableArray에 트윗을 추가 할 것을 알고 결코 수 :

은 그래서 당신이 아마해야 할 것은 다음과 같이 데이터의 재로드 수행하는 함수를 만드는 것입니다) 또한 짹짹이 추가되면 observableArray에 대한 구독을 시작합니다. 배열을 대체하려면 대체 배열을 만들고 해당 배열에 트윗을 넣고 마지막으로 self.tweets(replacementArray);을 수행하여 observableArray의 배열을 교체하십시오.

+0

감사합니다. 나는 그것이 그와 비슷한 것일 수도 있다고 생각했지만 그것을 보지 못했습니다. 이것으로 바로 해결되었습니다. 실마리를 가지고 나를 때리는 데 정말로 감사드립니다. – user3314493