2013-04-24 111 views
24

我目前正在基於web的twitter客戶端上工作,因此我使用angular.js,node.js和socket.io。我通過socket.io向我的客戶端推送新的推文,在那裏服務等待新的推文。當新的推文到達時,服務通過$ broadcast發送一個事件。angular.js:模型更新不會觸發視圖更新

在我的控制器是一個事件偵聽器,傳入的推文正在一個單獨的函數中處理。這個功能只是推動我的推特範圍內的新推文。

現在,我的問題是,我的觀點沒有更新,但我可以看到我的範圍在增長。也許你們有一個想法,我該如何解決這個問題?

另外我的代碼:

服務:

(function() { 
    app.factory('Push', ['$rootScope', function ($rootScope) { 
     socket.on('new-tweet', function (msg) { 
      $rootScope.$broadcast('new-tweet', msg); 
     }); 
    }]); 
}()); 

控制器:

(function() { 
    app.controller("StreamCtrl", function StreamCtrl ($scope, $rootScope, $http, Push) { 
     $scope.tweets = []; 

     $http 
      .get('/stream') 
      .then(function (res) { 
       $scope.tweets = res.data; 
      }); 

     $scope.addTweet = function (data) { 
      $scope.tweets.push(data); 
      console.log($scope.tweets); 
     }; 

     $rootScope.$on('new-tweet', function (event, data) { 
      if (!data.friends) { 
       $scope.addTweet(data); 
      } 
     }); 
    }); 
}()); 

整個項目是在這裏:https://github.com/hochitom/node-twitter-client

+2

嘗試添加$範圍$適用()在addTweet和看到的結果,如果觀點。更新與否 – 2013-04-24 07:39:01

回答

46

在addTweet和添加下面的代碼行問題將被解決

$scope.addTweet = function (data) { 
      $scope.tweets.push(data); 
      $scope.$apply(); 
      console.log($scope.tweets); 
     }; 
+6

謝謝。 $ scope。$ apply()幫助了我。只是好奇 - 這是更新視圖的正確方法嗎?意義,不應該角度「決定」範圍已經改變了嗎? – 2014-03-04 12:43:55

+3

這是一個很好的問題,http://jimhoskins.com/2012/12/17/angularjs-and-apply.html吉姆霍斯金斯有一個很好的總結,爲什麼'應用'在這種情況下,是必要的。 – KidA78 2014-06-29 00:34:14

+0

非常感謝您的回答。 $ scope。$ apply()爲我工作。我曾經使用$ injector.invoke(...)動態設置控制器。但無法獲取視圖中更新的$ scope變量。 $ scope變量只在按下按鈕或模糊時更新,但是當我使用$ scope。$ apply()時,$ scope變量在頁面最初加載時立即在視圖上更新。非常感謝。 – 2014-11-26 15:26:03

1

我更喜歡使用$timeout(不要忘了將它注入到控制器),而不是$apply

app.controller("StreamCtrl", function StreamCtrl ($scope, $timeout $rootScope, $http, Push) { 

    //... 

    $scope.addTweet = function (data) { 
     $timeout(function() { 
      $scope.tweets.push(data); 
      console.log($scope.tweets); 
     }); 
    }; 

    //... 

});