[英]AngularJS access element from controller in nested ng-repeat
I am kind of newbie in AngularJS world, and I'm running into a problem I have't been able to solve. 我是AngularJS世界的新手,遇到了一个我无法解决的问题。 I have a nested ng-repeat view, because I have a nested comment system, so I build the view from an object that is like this: 我有一个嵌套的ng-repeat视图,因为我有一个嵌套的注释系统,因此我是从这样的对象构建视图的:
comments: [{
_id: ObjectId(x),
parent_id: ObjectId(y),
text: 'Hello World!',
author: {
id: 1,
name: Jorge
}
replies: [{
_id: ...,
parent_id: ...
author: {
[...]
}
replies: [{
[...]
}]
},
{
[...]
}]
}]
So, every comment have a property named hearts
which are the number of likes that it has. 因此,每个评论都有一个名为hearts
的属性,该属性是它拥有的点赞数。 I have socket.io implemented so this is all running in real-time. 我已经实现了socket.io,所以这都是实时运行的。 In my controller I have a listener for a new like to a comment, the problem is, how I access a specific comment from my controller to update it likes? 在我的控制器中,我有一个侦听器,用于接收新的喜欢评论,问题是,如何从控制器访问特定评论以更新喜欢的评论?
I have tried by generating a dynamic id in the view like this ng-attr-id="{{'hearts_' + comment._id}}"
but this is just working for the parents comments, not for the replies, and I don't know why. 我尝试过在视图中生成动态ID,例如ng-attr-id="{{'hearts_' + comment._id}}"
但这仅适用于父母的评论,而不适用于回复,我不知道不知道为什么。
I have also tried to generate a function that looks for the comments and updates it, for instance this function: 我还尝试过生成一个查找注释并对其进行更新的函数,例如,以下函数:
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);
but with this function my $scope doesn't get updated in real-time, because I don't have the path to do it, I mean for example $scope.comments[2].replies[0].replies[3].replies[1]
但是使用此功能,我的$ scope不会实时更新,因为我没有执行此操作的路径,例如,我的意思是$scope.comments[2].replies[0].replies[3].replies[1]
I hope someone could help me with this because I am going mad! 我希望有人可以帮助我,因为我快疯了! I have read something about directives. 我已经阅读了一些有关指令的内容。 Could this be my solution? 请问这是我的解决方案吗?
Thank you very much. 非常感谢你。
A recursive directive makes the most sense, but Angular causes an infinite loop with recursive directives and it's a bit ugly to workaround. 递归指令最有意义,但是Angular会使用递归指令导致无限循环,解决方法有点难看。 You can use ng-include
recursively like this: Live demo (click). 您可以像这样递归地使用ng-include
: 现场演示(单击)。
<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>
This is the sample data I used: 这是我使用的示例数据:
$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'
}
}
]
}
]
}
];
For the updating when the socket message comes in, I would do this: 对于套接字消息传入时的更新,我可以这样做:
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;
});
});
Here's my function to get an array of matching comments. 这是我获取匹配注释数组的功能。 It uses lodash/underscore flatten
, but you could do that manually pretty easily if you want. 它使用lodash / underscore flatten
,但是您可以根据需要手动轻松地完成此操作。 It's best to be using npm modules so you can easily include lodash's flatten without bulking up your code with the whole library =D 最好使用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];
}
As you can see in this demo , the comment is updated as you wish. 如您在本演示中所看到的,评论将根据您的意愿进行更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.