我目前正在玩一個角度的應用程序,它使用websocket與後端進行通信。我有一些麻煩,讓角度的數據綁定正常工作。
在下面的例子中,我創建了一個創建websocket連接的服務。如果websocket收到消息,我只是將該消息推送到包含所有收到消息的數組中。
在我的控制器中,我將該消息數組綁定到示波器,然後使用ng-repeat
將它們全部列在我的局部視圖中。
服務:
factory('MyService', [function() {
var wsUrl = angular.element(document.querySelector('#ws-url')).val();
var ws = new WebSocket(wsUrl);
ws.onopen = function() {
console.log("connection established ...");
}
ws.onmessage = function(event) {
Service.messages.push(event.data);
}
var Service = {};
Service.messages = [];
return Service;
}]);
控制器:
controller('MyCtrl1', ['$scope', 'MyService', function($scope, MyService) {
$scope.messages = MyService.messages;
}])
部分:
<ul>
<li ng-repeat="msg in messages">
{{msg}}
</li>
</ul>
然而,這無法正常工作。當收到新消息並將其推入數組中時,應顯示所有消息的列表不會更新。我預計它會因爲角度雙向數據綁定而更新。
我發現一個解決方案,通過包裝的消息推到一個呼叫服務工程$rootScope.apply()
:
ws.onmessage = function(event) {
$rootScope.$apply(function() {
Service.messages.push(event.data);
});
}
我的問題是:
這是預期角度的行爲,如果我不使用
$rootScope.apply()
,我的列表不會自動更新?爲什麼我甚至需要把它包裝在
$rootScope.apply()
?正在使用
$rootScope.apply()
正確的方法來解決這個問題?對於這個問題,
$rootScope.apply()
有更好的選擇嗎?
所以,你說的任何東西'$ timeout'包裹,會自動應用正確的? – aacanakin
是@aacanakin $ timeout的回調函數中的任何同步代碼都會自動應用。 – Juliano