我是AngularJS世界的新手,我遇到了一个我无法解决的问题。 我有一个嵌套的ng-repeat视图,因为我有一个嵌套的注释系统,所以我从一个像这样的对象构建视图:
comments: [{
_id: ObjectId(x),
parent_id: ObjectId(y),
text: 'Hello World!',
author: {
id: 1,
name: Jorge
}
replies: [{
_id: ...,
parent_id: ...
author: {
[...]
}
replies: [{
[...]
}]
},
{
[...]
}]
}]
因此,每个评论都有一个名为hearts
的属性,它是它拥有的喜欢的数量。
我已经实现了socket.io,所以这些都是实时运行的。在我的控制器中,我有一个喜欢评论的新听众,问题是,我如何从我的控制器访问特定评论以更新它?
我已尝试在视图中生成动态ID,例如ng-attr-id="{{'hearts_' + comment._id}}"
,但这只适用于父母的评论,而不是回复,我不知道为什么。
我还试图生成一个查找注释并更新它的函数,例如这个函数:
var setNewHearts = function(comments, comment) {
for (var i = 0; i < comments.length; i++) {
if ((String(comments[i]._id)) == (String(comment._id))) {
comments[i].hearts = eventData.comment.hearts;
return comments;
} else if (comments[i].replies) {
setNewHearts(comments[i].replies, eventData.comment);
} else {
//$scope.showMoreComments = true;
}
}
}
console.log(eventData.comment);
$scope.comments = setNewHearts($scope.comments, eventData.comment);
但是使用这个函数我的$ scope不会实时更新,因为我没有路径去做,我的意思是例如$scope.comments[2].replies[0].replies[3].replies[1]
我希望有人可以帮助我,因为我疯了!我读过一些关于指令的内容。这可能是我的解决方案吗?
非常感谢。
答案 0 :(得分:2)
递归指令最有意义,但Angular会导致带有递归指令的无限循环,并且解决方法有点难看。您可以递归使用ng-include
,如下所示:Live demo (click).
<div ng-repeat="comment in comments" ng-include="'comment.html'"></div>
<script type="text/ng-template" id="comment.html">
<div>
<p>{{comment.author.name}}: {{comment.text}}</p>
<div class="reply" ng-repeat="comment in comment.replies" ng-include="'comment.html'"></div>
</div>
</script>
这是我使用的样本数据:
$scope.comments = [
{
id: 1,
text: 'Hello World!',
author: {
id: 1,
name: 'Jorge'
},
replies: [
{
id: 2,
text: 'Hey, Jorge!',
author: {
id: 2,
name: 'World'
},
replies: [
{
id: 3,
text: 'Woah!',
author: {
id: 1,
name: 'Jorge'
}
}
]
}
]
}
];
对于套接字消息进入时的更新,我会这样做:
socket.on('comment-liked', function(commentId) {
$scope.$apply(function() {
// recursively search all objects and return object where `obj.id === commentId`
var comment = findCommentById($scope.comments, likedCommentId);
// increment the counter or set to 1 if there were no hearts before
comment.hearts = comments.hearts ? ++comment.hearts : 1;
});
});
这是我获取一系列匹配注释的函数。它使用lodash /下划线flatten
,但如果你愿意,你可以很容易地手动完成。最好是使用npm模块,这样你就可以很容易地包含lodash的flatten,而不需要用整个库扩展你的代码= D
function findCommentById(comments, id) {
return _.flatten(comments.map(function(comment) {
if (comment.id === id) { return comment; }
return findCommentById(comment.replies, id);
}))[0];
}
正如您在this demo中所看到的,评论会根据您的意愿进行更新。