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



我确定这是一个非常普遍的问题,但由于某种原因,我找不到有效的解决方案。

我对Firebase Realtime Database和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 中的开发工具进行了验证(,html 也不会更新:/

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

$rootScope不适合存储用户对象。一般来说,在没有其他选择的情况下,修改$rootScope应该被认为是你做的事情。

您应该做的是创建一个用户服务并将其注入到您需要访问用户数据的任何位置。

同样的建议通常也适用于使用 ng-init。我猜你刚刚开始使用Angularjs。我强烈建议你熟悉John Papa的Angularjs风格指南:https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md。它有点过时,因为它没有涵盖组件,这是所有内容,但遵循样式指南使迁移到组件变得非常容易。

这里的解决方案似乎有效:Firebase 回调和 AngularJS

有点笨拙,但我想它有效。谢谢那些回答的人。

正如我在上面的评论中提到的,我会把范围.$apply放在事件侦听器b/cAngularJS不知道事件何时被触发,因为它没有管理它。 即:

usersRef.on('value', scope.$apply(function () { 
console.log("loaded users list");
var users = snapshot.val();
updateUsersTable(users);
}));

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

$evalAsync([表达式], [locals](;在 稍后时间点的当前范围。

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

它将在计划评估的函数之后执行 (最好在 DOM 渲染之前(。至少一个$digest周期将是 在表达式执行后执行。

最新更新