在 post 中加载评论
Load comments in post
假设我的 Firebase 数据库中有这个结构
已编辑:
我的 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:{...}
}
}
我在控制器中检索用户(每个用户都有一个 属性 post)以使用 $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>
所以现在,问题是当它们位于不同的节点时,我如何查询以请求每个 post 的所有评论,我按 ID 存储它们但仍然不知道如何做吧。
在我将评论存储在每个用户内部并且可以显示每个 post 上的评论之前,但是我在安全规则方面遇到了问题,因为我已经指定用户只能修改它自己的内容而不是其他内容,并且将评论留在用户内部不允许其他人发表评论,所以我不得不更改并将评论放在不同的节点中。
你的数据保持平稳,太棒了!
您还在两个位置之间使用共享密钥,这意味着您已经完成了 90%。
有多种方法可以处理这种情况,但 using .$extend()
in AngularFire 提供了一个优雅的解决方案。
下面的代码示例使用了 Angular Styleguide,所以如果代码看起来不熟悉,请不要担心。
Here's the full demo on JSBin,下面是创建步骤。
我们想为每个用户加载评论。我们将首先创建一个工厂,通过 uid
:
获取 ad-comments
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 });
};
}
我不是 Firebase 专家,但我认为您应该考虑如何为 post 及其评论之间的联系建模。
我可以想到两种方法:
Post实体将有一个附加字段:
列出 commentIds
评论实体将持有 post
的 ID
我推荐第一种方法,因为通常我们希望所有者实体(在本例中为 Post 实体)持有其子实体(评论)
现在,当您检索 Post 时,请务必使用评论 ID 检索其所有评论。
假设我的 Firebase 数据库中有这个结构
已编辑: 我的 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:{...}
}
}
我在控制器中检索用户(每个用户都有一个 属性 post)以使用 $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>
所以现在,问题是当它们位于不同的节点时,我如何查询以请求每个 post 的所有评论,我按 ID 存储它们但仍然不知道如何做吧。
在我将评论存储在每个用户内部并且可以显示每个 post 上的评论之前,但是我在安全规则方面遇到了问题,因为我已经指定用户只能修改它自己的内容而不是其他内容,并且将评论留在用户内部不允许其他人发表评论,所以我不得不更改并将评论放在不同的节点中。
你的数据保持平稳,太棒了!
您还在两个位置之间使用共享密钥,这意味着您已经完成了 90%。
有多种方法可以处理这种情况,但 using .$extend()
in AngularFire 提供了一个优雅的解决方案。
下面的代码示例使用了 Angular Styleguide,所以如果代码看起来不熟悉,请不要担心。
Here's the full demo on JSBin,下面是创建步骤。
我们想为每个用户加载评论。我们将首先创建一个工厂,通过 uid
:
ad-comments
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 });
};
}
我不是 Firebase 专家,但我认为您应该考虑如何为 post 及其评论之间的联系建模。 我可以想到两种方法:
Post实体将有一个附加字段:
列出 commentIds
评论实体将持有 post
的 ID
我推荐第一种方法,因为通常我们希望所有者实体(在本例中为 Post 实体)持有其子实体(评论)
现在,当您检索 Post 时,请务必使用评论 ID 检索其所有评论。