我目前正在玩一个角度的应用程序,它使用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