我有一个关于使用angular和Firebase进行异步加载的问题。 我有一个用户模型和一个语言模型;用户可以拥有多种语言,这意味着User模型具有一个名为“languages”的属性,即一个数组。
我可以通过以下方式获取当前用户:
$scope.user = User.findByUsername($routeParams.username)
一旦用户加载,我就可以采取一些行动。我想采取的行动是找到 数据库中的语言对象基于用户的语言ID。也就是说,我不想说'John User speaks IDXXXXXXX',而是想说'John User会说英语'。
$scope.user.$on('loaded', function(){
angular.forEach($scope.user.languages, function(id){
$scope.userLanguages[id] = Language.find(id);
});
});
这有时会起作用,但并非总是如此。很明显,问题在于我通过ID查找语言的方式 - 有时它超级快且$ scope.userLanguages [id]意味着什么,有时候它不够快而且id是'undefined'。这几乎就像我需要为Language.find()添加另一个$ on('loaded')监听器。但后来我进入了一组复杂的嵌套式监听器,这看起来很疯狂。
我在这里缺少什么?
// The basic structure of data in my Firebase database
languages
-IDXXXXXXXX
name: 'English',
localName: 'English'
-IDXXXXXXXX
name: 'Spanish',
localName: 'Espanol'
users
-SomeName
username: 'Whatever',
languages: [IDXXXX, IDXXXY, etc]
在制作我的问题时,我发现以下内容可能有效。它确实如此,但将一个$放在另一个上面感觉很奇怪。这是否表明我应该寻找更好的方法来构建我的数据和代码?或许它很好......
$scope.user.$on('loaded', function(){
angular.forEach($scope.user.languages, function(id){
var lang = Language.find(id);
lang.$on('loaded', function(){
$scope.userLanguages[id] = Language.find(id);
$scope.languages[id].selected = true;
});
});
});
答案 0 :(得分:1)
由于保证loaded
事件只被调用一次,因此可以嵌套它们。但是,假设Language.find
正在返回$firebase
实例,则可能没有必要;你可以立即分配;它会在数据到达时更新。
$scope.user.then(function() { // as of 0.7.2, this is equivalent to $on('loaded')
angular.forEach($scope.user.languages, function(id) {
$scope.userLanguages[id] = Language.find(id);
});
});
要记住的一件事是,“加载”事件只会触发一次,因此如果用户的语言索引在将来发生变化,$scope.userLanguages
和$scope.languages
都不会更新,因为这不是实时监控的。
如果您想添加实时监控,可以执行以下操作,而不是使用loaded
事件:
$scope.user.$child('languages').$on('child_added', function(snap) {
var id = snap.snapshot.name;
$scope.userLanguages[id] = Language.find(id);
});