我正试图用AngularJS和套接字服务器构建一个实时应用程序。我试着遵循John Papas Angular Styleguide
我有一个叫mainFactory的工厂:
...
socket.on('buylist', function(list) {
buylist = list;
$rootScope.$broadcast('buylist');
});
...
mainFactory.getBuylist = function () {
return buylist;
}
对于控制器,我使用ControllerAs语法,因此我构建了一个视图模型变量。homeController:
var vm = this;
$scope.$on('buylist', function(e) {
vm.buylist = mainFactory.getBuylist();
console.log('TO TEST WHEN THE EVENT IS FIRED!')
});
在视图中:
<li ng-repeat="listitem in home.buylist">
...
</li>
这很好但在事件触发2-5秒后,视图会更新。但我希望视图能立即更新。
我通过在事件上使用$scope而不是vm和$apply()it来实现这一点:
$scope.$on('buylist', function(e) {
$scope.buylist = mainFactory.getBuylist();
$scope.$apply();
});
在视图中:
<li ng-repeat="listitem in buylist">
...
</li>
所以现在一切都是实时的但样式指南说,我应该尽可能避免使用$scope,而是使用ViewModel ControllerAs方式。因此,我正在寻找一种$应用ViewModel的方法,或者在事件触发后立即更新视图的其他方法。
问题是套接字中的事件根本不知道AngularJS。只有在摘要周期中对模型进行更改时,角度才会更新视图。若您在它之外更改模型,那个么无论出于何种原因,您的更改都将反映在下一个摘要中。
在大多数情况下,您不需要意识到这一点,前提是您一直"保持在Angular中"(例如,当您使用ng-click
处理单击事件时,会自动启动摘要循环)。
然而,当您想要处理非Angular事件(即套接字事件或jQuery事件等)时,您必须关心它才能使一切正常工作。为了使其最透明,我会将您的套接字侦听器更改为:
socket.on('buylist', function(list) {
$rootScope.$apply(function() {
buylist = list;
$rootScope.$broadcast('buylist');
});
});
你可能想阅读更多关于这个主题的内容,看看这个类似的问题。