【问题标题】:"Error: $apply already in progress" when using FireBaseAuthClient with AngularJS将 FireBaseAuthClient 与 AngularJS 一起使用时出现“错误:$apply 已在进行中”
【发布时间】:2013-05-03 08:56:53
【问题描述】:

我正在尝试在 AngularJS 范围内记录登录用户,但在页面首次加载时出现错误。

单击“登录”似乎可以工作,但随后注销会出现相同的“$apply already in progress”错误。

我想我只是误解了$apply 的工作原理,有人可以帮忙吗?

更新

如果我只将if (user) 部分包装在$apply() 中,它可以无缝工作,如下所示。

var auth = new FirebaseAuthClient(ref, function(error, user) {
    if (user) {
        $scope.$apply(function(){ $scope.user = user; });
        console.log(user);
    } else if (error) {
        // I can't vouch for this, haven't tested it
        $scope.$apply(function(){ $scope.user = null; });
        console.log(error);
    } else {
        $scope.user = null;
        console.log("logged out");
    }
});

原始代码

app.js:

var app = angular.module('app', ['firebase']);

controller.js:

app.controller('Login', ['$scope', 'angularFire',
function($scope, angularFire) {
    $scope.loginstatus = 'logged out';

    var ref = new Firebase("https://app.firebaseio.com/");
    var auth = new FirebaseAuthClient(ref, function(error, user) {
        if (user) {
            $scope.$apply(function(){ $scope.loginstatus = 'logged in'; });
        } else if (error) {
            $scope.$apply(function(){ $scope.loginstatus = 'error'; });
            alert("Login error: " + error);
        } else {
            $scope.$apply(function(){ $scope.loginstatus = 'logged out'; });
        }
    });

    $scope.login = function(provider, args) {
        auth.login(provider, args);
    }

    $scope.logout = function() {
        auth.logout();
    }
}]);

index.html:

<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
    <meta charset="utf-8">
    <title>App</title>
    <script type="text/javascript" src="https://cdn.firebase.com/v0/firebase.js">
    <script type="text/javascript" src='https://cdn.firebase.com/v0/firebase-auth-client.js'></script></script>
    <script type="text/javascript" src="lib/angular/angular.js"></script>
    <script type="text/javascript" src="lib/angularFire.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
    <script type="text/javascript" src="js/controllers.js"></script>
</head>
<body ng-controller="Login">
    <p>Login status: {{loginstatus}}</p>
    <div class="container">
      <h1>Login</h1>
      <p>
        <button ng-hide="user" ng-click="login('twitter')" class="btn btn-primary btn-large">Login</button>
        <button ng-show="user" ng-click="logout()" class="btn btn-primary btn-large">Logout</button>
      </p>
    </div>
</body>
</html>

【问题讨论】:

    标签: angularjs firebase angularfire


    【解决方案1】:

    $apply 仅在您处于 Angular 上下文之外(如 setTimeout、setInterval 或非 Angular XHR 回调)时才需要。

    由于 FireBaseAuthClient 是一个使用 Angular 编写并注入控制器的工具,因此回调很可能已经包含在 $scope.$apply 中。您可以通过删除 $scope.$apply 来修复您的代码,因此只需:

    var ref = new Firebase("https://app.firebaseio.com/");
    var auth = new FirebaseAuthClient(ref, function(error, user) {
        if (user) {
            $scope.loginstatus = 'logged in';
        } else if (error) {
            $scope.loginstatus = 'error';
            alert("Login error: " + error);
        } else {
            $scope.loginstatus = 'logged out';
        }
    });
    

    【讨论】:

    • 为回复干杯,但这不起作用。这就是我必须开始的。回调有效,因为如果我将它推到那里,我可以看到控制台输出,但 $scope 没有得到更新。这是不是“内部角度”的症状,因此我开始摆弄$apply()
    • 如果我只包装“登录”逻辑并像上面一样保留注销逻辑,它就可以工作。请参阅我的原始问题以获取更新。
    • 话虽如此,您可能需要在promise 中使用$apply。仅供参考。
    猜你喜欢
    • 1970-01-01
    • 2014-05-25
    • 2014-02-10
    • 2016-02-22
    • 2013-09-08
    • 2019-03-20
    • 2021-06-25
    • 2018-06-16
    • 1970-01-01
    相关资源
    最近更新 更多