假设我的Firebase DB中有这个结构
编辑: 我的JSON结构如下所示:
{
ad-comments:{
48a047b7-28a2-4037-925c-2a809b8d4445:{
-K4iGKXbniQZUi4r1SW7:{
Comment:""
Email:""
Date:""
Submitter:""
ID:""
}
-K4hxcKuuxcwuhScPR_v:{...}
}
eeb082e5-59ed-4c3b-8fcd-5af24a2bcada:{...}
}
users:{
48a047b7-28a2-4037-925c-2a809b8d4445:{
text:""
name:""
email:""
desc:""
phone:""
}
444198db-1052-4d8d-a1cd-c7e613fbe7c9:{...}
}
}
在控制器中我检索用户(每个用户都有一个属性帖子),使用$ firebaseArray和ng-repeat在视图中显示它们,如下所示:
var ref = new Firebase ("https://url.firebaseio.com/users");
$scope.posts = $firebaseArray("ref");
现在在视图中我只是使用ng-repeat来迭代它们
<div ng-repeat="post in posts">
<div>{{post.name}}</div>
<div>{{post.text}}</div>
<div>Comments:<div>
<div><input type="text" ng-model="comment"></div>
<div><button ng-click="addComment(post, comment)">Add</button></div>
</div>
现在,问题是如何在每个帖子位于不同节点时进行查询以请求所有评论,我按ID存储它们但仍无法弄清楚如何操作。
在我将评论存储在每个用户中之前,可以在每个帖子上显示评论,但我遇到了安全规则的问题,因为我已经指定用户只能修改自己的内容而不是其他人,并将评论留在用户内部并不允许其他人发表评论,所以我不得不改变并将评论放在不同的节点中。
答案 0 :(得分:3)
您保持数据平稳,这太棒了!
您还在两个位置之间使用共享密钥,这意味着您将有90%的位置。
有多种方法可以处理这种情况,但using .$extend()
in AngularFire提供了一个优雅的解决方案。
下面的代码示例使用Angular Styleguide,所以如果代码看起来不熟悉,请不要担心。
Here's the full demo on JSBin以及以下是创建它的步骤。
我们希望为每个用户加载评论。我们首先创建一个工厂,ad-comments
uid
:
function UserCommentsArray($firebaseArray, rootRef) {
return function UserCommentsArray(uid) {
var userCommentsRef = rootRef.child('ad-comments').child(uid);
return $firebaseArray(userCommentsRef);
};
}
现在我们将使用$firebaseArray.$extend()
创建自定义同步数组。
function UsersArray($firebaseArray, rootRef, userCommentsArray) {
return $firebaseArray.$extend({
$$added: function(snap) {
var user = snap.val();
user.$id = snap.key();
user.comments = userCommentsArray(snap.key());
return user;
}
});
}
每次将一个项目添加到数组中时,我们都会创建一个用户对象并添加userCommentsArray
的评论。
现在在我们的控制器代码中,我们可以简单地注入usersArray
并绑定到页面。
function MyCtrl($scope, rootRef, usersArray) {
var usersRef = rootRef.child('users');
$scope.users = usersArray(usersRef);
}
在页面上显示此数据需要更改模板:
<div ng-controller="MyCtrl">
<div ng-repeat="user in users">
<div>{{user.name}}</div>
<ul ng-repeat="comment in user.comments">
<li>{{ comment.text }}</li>
</ul>
<div>Comments:</div>
<div>
<input type="text" ng-model="newComment">
</div>
<div>
<button
ng-click="addComment(user, newComment)">Add
</button>
</div>
</div>
</div>
在用户下添加评论是通过找到用户然后在评论数组上调用$add()
来完成的。
function MyCtrl($scope, rootRef, usersArray) {
var usersRef = rootRef.child('users');
$scope.users = usersArray(usersRef);
$scope.addComment = function (user, newComment) {
var userRecord = $scope.users.$getRecord(user.$id);
userRecord.comments.$add({ text: newComment });
};
}
答案 1 :(得分:1)
我不是Firebase专家,但我认为您应该考虑如何建模帖子及其评论之间的联系。 我可以想到两种方式:
发布实体将有一个额外的字段:
列出commentIds
评论实体将保留帖子的ID
我建议采用第一种方法,因为通常我们希望所有者实体(在本例中为Post实体)保留其子项(评论)
现在,当您检索帖子时,请确保使用评论ID检索其所有评论。