AngularJS - 从Angular外部触发摘要的最佳方法

时间:2015-02-26 04:47:16

标签: javascript angularjs

我不太确定标题是最好的描述,但我想知道如果我在Angular摘要循环之外发生了一些事件,触发摘要循环,最好的方法是什么?在我正在处理的应用程序中,我正在使用Socket.io来从网络中的其他应用程序来回传递数据。 Socket.io中有一些事件可用于更新当前Controllers $范围内的模型。在发生摘要循环之前,这些更改不会反映在UI中。我不希望调用$ scope。$ apply()以防止遇到Angular已经处于循环中的问题。

我知道我可以使用$ timeout()并将我的函数放在那里并将超时设置为0秒。这就是我目前正在使用它并且工作正常,但我想知道这是否是最好的方法?

示例JS

var app = angular.module('MyApp',[]);
var socket = io.connect('http://localhost:3000');

app.controller('MyAppController',['$scope',function($scope) {
    $scope.connections = 0;
    socket.on('connect',function(sock) {
        sock.on('event',function() {
            $scope.connections++;
        };
    };
}]);

示例HTML

<!DOCTYPE html>
<html lang="en" ng-app="MyApp">
<head></head>
<body ng-controller="MyAppController">
    <p>Connections: {{connections}}</p>
    <script src="angular.min.js"></script>
</body>
</html>

显然,这是一个非常简单的,尽可能基本的例子。它不是正在使用的ACTUAL代码,但代表了同样的问题。当从socket.io引发事件时,$ scope.connections变量会递增但是UI不反映更改,直到其他东西触发摘要循环,$ scope。$ apply()被调用,或者我使用$ timeout ()。

再一次,我有适用的代码,只是想知道最好的方法是什么。

由于

1 个答案:

答案 0 :(得分:12)

每当您知道自己不在摘要循环中时,调用$ scope。$ apply()或$ scope.digest()始终是安全的(也是最佳做法)。你怎么知道的?任何不通过Angular API完成的异步调用。这是角度在内部处理这些情况的方式(查看ngEvent指令的代码)。

仅当您无法确定正在运行的代码是否在&#34;内部&#34;角度与否。这应该是非常非常罕见的。我只需要这一次,而且我仍然不高兴......

var app = angular.module('MyApp',[]);
var socket = io.connect('http://localhost:3000');

app.controller('MyAppController',['$scope',function($scope) {
    $scope.connections = 0;
    socket.on('connect',function(sock) {
        sock.on('event',function() {
            //wraps your code in a try catch that is handled by angular's error service.  Calls $rootScope.$digest()           
            $scope.$apply(function() {
                $scope.connections++;
            });

            //OR - errors in your code will not be handled by angular
            //also calls $rootScope.$digest()
            $scope.connections++;
            $scope.$apply();

            //OR - errors in your code will not be handled by angular
            //Only processes watchers for $scope and it's children
            //Fastest, but may have unintended consequences.
            $scope.connections++;
            $scope.$digest();
        };


    };
}]);

我更喜欢第一个选项,因为它可以获得你的代码&#34;在angular&#34;中。但是,这三个都可行。