Update/apply ViewModel 事件

Update/apply ViewModel on event

我正在尝试使用 AngularJS 和套接字服务器构建一个实时应用程序。 我试着关注 John Papas Angular Styleguide

我有一个名为 mainFactory 的工厂:

...
socket.on('buylist', function(list) {
            buylist = list;
            $rootScope.$broadcast('buylist');
        });
...
mainFactory.getBuylist = function () {
            return buylist;
        }

对于控制器,我使用 ControllerAs 语法,因此我构建了一个视图模型变量。 家庭控制器:

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() 让它工作:

$scope.$on('buylist', function(e) {
    $scope.buylist = mainFactory.getBuylist();
    $scope.$apply();
});

在视图中:

<li ng-repeat="listitem in buylist">
...
</li>

所以现在一切都是完美的实时但是风格指南说我应该尽可能避免使用 $scope 并改用 ViewModel ControllerAs 方式。所以我正在寻找的是一种 $apply ViewModel 的方法或其他一些在事件被触发后立即更新视图的方法。

问题是来自您的套接字的事件根本不知道 AngularJS。 Angular 仅当在 digest cycle 期间对模型进行更改时才更新视图。如果您在其外部更改模型,无论出于何种原因,您的更改都会反映在下一个摘要中。

在大多数情况下,只要您一直"stay in Angular"(例如,当您使用ng-click处理点击事件时,摘要循环就开始了,您就不需要知道这一点自动为您服务)。

然而,当你想处理非Angular事件(即套接字事件,或jQuery事件等)时,你必须关心它以使一切正常。为了使其最透明,我会将您的套接字侦听器更改为:

socket.on('buylist', function(list) {
    $rootScope.$apply(function() {
        buylist = list;
        $rootScope.$broadcast('buylist');
    });
});

您可能想要 read more on this topic and see this similar problem