如何在异步回调中更新Angular 1中的$ rootScope?

时间:2017-07-25 19:35:52

标签: html angularjs firebase firebase-realtime-database

我确定这是一个非常常见的问题,但出于某种原因,我无法找到有效的解决方案。

我使用Firebase实时数据库和Angular 1进行了非常简单的设置。我的html中有这个指令

<div id="usersListWrapper" ng-controller="UsersListController" ng-init="loadUsersList()">

然后在我的loadUsersList()方法中,我调用Firebase数据库来获取数据

$rootScope.users = [];

var usersRef = firebase.database().ref('/users');
usersRef.on('value', function(snapshot) {
    console.log("loaded users list");
    var users = snapshot.val();
    updateUsersTable(users);
});

最后,在updateUsersTable(users)内,我更新了我的$rootScope.users变量

var updateUsersTable = function(users) {
    $.each(users, function(key, value) {
        var user = {
            username: key,
            ...
        }

        $rootScope.users.push(user);
    }
}

但是,即使$rootScope.users变量正确更新(我使用Chrome中的devtools验证),html也不会更新:/

如果这是一个重复的问题,请提前道歉。帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

$ rootScope不适合存储用户对象。一般来说,修改$ rootScope时应该考虑在没有其他选项的情况下执行的操作。

您应该做的是创建一个userService并在您需要访问用户数据时将其注入。

同样的建议通常也适用于使用ng-init。我猜你刚刚开始使用Angularjs。我强烈建议您熟悉John Papa的Angularjs风格指南:this SO answer。它有点过时,因为它没有涵盖组件,这是一切,但遵循风格指南使迁移到组件非常容易。

答案 1 :(得分:0)

此处的解决方案似乎有效:Firebase callbacks and AngularJS

有点hacky,但我认为它有效。感谢那些回答的人。

答案 2 :(得分:0)

正如我在上面的评论中提到的,我会将范围。$ apply 放在事件监听器上b / c AngularJS 不知道事件何时发生因为没有管理它而解雇了。即:

"Ærøskøbing Brugs".parameterize(preserve_case: true) => "AEroskobing-Brugs"

或者您可以查看 $ evalAsync 。来自AngularJS文档:

  

$ evalAsync ([表达式],[本地人]);执行表达式   目前的范围在以后的时间。

     

$ evalAsync不保证表达式何时出现   执行,只有:

     

它将在安排评估的功能之后执行   (最好在DOM渲染之前)。至少有一个$摘要周期   表达式执行后执行。