AngularFire 0.82 - 如何查询非规范化数据?

时间:2014-11-07 22:04:45

标签: javascript angularjs firebase angularfire

此问题与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服务”中的代码

1 个答案:

答案 0 :(得分:3)

理解我们试图解决的用例而不仅仅是解决问题的解决方案(通常会有所帮助) - 通常有更简单的方法来解决问题集(参见{ {3}})。

AngularFire没有内置处理嵌套列表的列表。特定元素的列表实际上比从列表中引用的几个列表容易得多。

Firebase.util

一个名为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数据并将其转换为任何专有结构的非常详尽的讨论。