【问题标题】:AngularJS - Best method to trigger digest from outside of AngularAngularJS - 从 Angular 外部触发摘要的最佳方法
【发布时间】:2015-02-26 04:47:16
【问题描述】:

我不太确定标题是否是最好的描述,但我想知道如果我有一些发生在 Angular 摘要循环之外的事件来触发摘要循环,最好的方法是什么?在我正在处理的应用程序中,我使用 Socket.io 从网络中的其他应用程序来回传递数据。来自 Socket.io 的一些事件可用于更新当前控制器 $scope 内的模型。但是,在出现摘要循环之前,这些更改不会反映在 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>

显然,这是一个非常精简、尽可能基本的示例。这不是实际使用的代码,而是代表相同的问题。当从 socket.io 引发事件时,$scope.connections 变量会增加,但 UI 不会反映更改,直到其他东西触发摘要循环,调用 $scope.$apply(),或者我使用 $timeout ()。

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

谢谢

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

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

    仅当您不确定您正在运行的代码是否“内部”有角度时才使用 $timeout。这应该是非常非常罕见的。我只需要这个一次,我仍然对此不太满意......

    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();
            };
    
    
        };
    }]);
    

    我更喜欢第一个选项,因为它可以让您的代码“在角度内”。但是,这三个都可以工作。

    【讨论】:

      猜你喜欢
      • 2016-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      • 2021-05-08
      • 1970-01-01
      相关资源
      最近更新 更多