此问题与AngularFire - How do I query denormalised data?类似,但我确实想要一个使用AngularFire的答案(当前版本为0.82)。 这是我使用的数据结构的一个例子:
{
"users": {
"user1": {
"name": "Alice",
"lists": {
"list1": "true"
}
},
"user2": {
"name": "Bob",
"lists": {
"list2": "true"
}
}
},
"lists": {
"list1": {
"title": "Example"
},
"list2": {
"title": "Example2"
}
}
}
或者,用另一种表示法: 为了获得所有这些用户的列表,我们需要以下所有这些:
users/$userID/lists/$listID
并且列表的内容存储在:
下lists/$listID
我想要实现的是能够访问特定用户列表的内容,但无需“手动”迭代每个$ ListID。
一个更好的答案可以包括在AngularFire扩展服务中包含该访问的代码,类似于AngularFire docs下的“创建AngularFire服务”中的代码
答案 0 :(得分:3)
理解我们试图解决的用例而不仅仅是解决问题的解决方案(通常会有所帮助) - 通常有更简单的方法来解决问题集(参见{ {3}})。
AngularFire没有内置处理嵌套列表的列表。特定元素的列表实际上比从列表中引用的几个列表容易得多。
一个名为What is the XY problem?的工具可以帮助进行非规范化(它目前正在加速到V2,在一两个月内到期),并且它与AngularFire兼容:
var fbRef = new Firebase(URL);
var indexRef = fbRef.child('users/' + userId + '/lists');
var dataRef = fbRef.child('lists');
var joinedRef = Firebase.util.intersection(indexRef, dataRef);
var lists = $firebase( joinedRef ).$asArray();
仅限角度的方法是手动加载列表并将AngularFire用于各个列表:
app.factory('NestedList', function($firebase, $timeout) {
return function(indexRef, dataRef) {
var hashOfLists = {};
indexRef.on('child_added', function(snap) {
var key = snap.key();
var list = $firebase( dataRef.child(key).$asArray();
hashOfLists[key] = list;
});
indexRef.on('child_removed', function(snap) {
$timeout(function() {
delete hashOfLists[snap.key()];
});
});
return hashOfLists;
}
});
请注意,此示例使用snap.key(),但仅在使用SDK的版本2.x时才适用,该版本刚刚在本周发布; prev版本应使用snap.name()
要获得更高级的操作并创建自己的指令或服务,请查看Firebase.util。虽然乍一看可能不会出现,但这是一个关于如何获取任何Firebase数据并将其转换为任何专有结构的非常详尽的讨论。