AngularJS $ scope。$ apply()困境

时间:2016-06-21 09:21:53

标签: javascript angularjs firebase firebase-realtime-database

我正在使用AngularJS和Firebase实时数据库来创建一个简单的列表应用程序,它可以跨设备同步。 Web客户端代码可以在下面找到。

问题是我需要在我的Firebase on('val')回调中使用$ scope。$ apply函数,因为此回调是从AngularJS外部执行的,没有它,绑定不会更新。但是,当用户输入新的列表项并单击“添加”按钮时,我看到angular.js:12520 Error: [$rootScope:inprog]。我认为发生这种情况是因为当我已经在$digest()内时,我正在调用$digest()方法。

那么我怎样才能实现我想做的事情呢?当在AngularJS之外触发回调时使用显式$digest()方法,否则不使用它。

<html>
    <head>
        <script src="https://www.gstatic.com/firebasejs/live/3.0/firebase.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            var config = {
                apiKey: "XXX",
                authDomain: "XXX",
                databaseURL: "XXX",
                storageBucket: "XXX",
            };
            firebase.initializeApp(config);
            var app = angular.module('myApp', []);
            app.controller('myCtrl', function($scope) {
                var database = firebase.database();
                database.ref().on('value', function(snapshot) {
                    $scope.$apply(function() {
                        $scope.items = [];
                        var result = snapshot.val();
                        for(var key in result) {
                            var listItem = result[key];
                            $scope.items.push(listItem);
                        }
                    });
                });
                $scope.addItem = function () {
                    database.ref().push().set($scope.addMe);
                }
            });
        </script>
        <div ng-app="myApp" ng-controller="myCtrl">
            <ul>
                <li ng-repeat="x in items">{{x}}</li>
            </ul>
            <input ng-model="addMe">
            <button ng-click="addItem()">Add</button>
        </div>
    </body>
</html>

1 个答案:

答案 0 :(得分:2)

FIX 1 -

使用

$timeout(function(){ 
  $scope.$apply()
  ... write your code here 
},0)

摘要周期结束后会触发。

FIX 2 -

如果摘要周期正在运行,则

$scope.$$phase将返回true,否则它将无效,因为它不提供任何回调函数。

也不建议使用