我一直在使用Angularjs一段时间,并遇到了一个奇怪的问题。
我将返回的数据渲染到ng-repeat
我能够列出由项目_id排序的数据,从而显示最新的数据。但是当我创建一个插入新项目并使用push
的添加功能时,后续项目被添加到列表的底部(当它需要位于顶部时)这没什么大不了的,因为我刚刚创建了一个orderBy过滤器:
data-ng-repeat="post in posts | orderBy:'_id':true"
这样就可以了,当添加一个新项目时,bingo会有效地添加到ng-repeat列表中。但是(这是棘手的部分)每个项目,包括新添加的项目都有能力被编辑和删除。这可以通过以下方式完成:
// within ng-repeat
ng-click="deletePost($index,post._id)"
// Subséquent function
$scope.deletePost = function(idx, id) {
// Delete Post
Blog.Post.delete({ id:id }, function(success) {
$scope.posts.splice(idx, 1);
})
}
上面确实从数据库中删除了该项目,但是在ng-repeat列表中,它删除了要删除的所需项目下面的项目。有没有人以前遇到过这个问题?或者可能的解决方法?
这可能与track by
有关吗?
另请注意,如果我完全删除orderBy
过滤器,则删除和编辑会有效。但后来我回到了我开始的地方,并且这是一个新添加的项目附加到底部而不是顶部。
答案 0 :(得分:3)
原因是因为与带有orderBy的ng-repeated项目相比,$scope.posts
具有原始订单的项目。 Orderby过滤器重新排列项目,返回一个新数组并重复它而不是原始的$scope.posts
数组。因此,如果原始订单与排序顺序不同,则索引将不同。
而且我相信你只是过度使用东西,只需按原样传递对象并从原始列表中获取拼接索引。
只需从ng-click传递帖子:
ng-click="deletePost(post)"
并在控制器中:
$scope.deletePost = function(post) { //Get post object
var posts = $scope.posts;
/*Delete with the _id property*/
Blog.Post.delete({ id:post._id }, function(success) {
/*Get the original index with the object reference and splice it*/
posts.splice(posts.indexOf(post), 1);
});
}
angular.module('app', []).controller('ctrl', function($scope) {
$scope.posts = [{
_id: 'id1',
name: 'Post1'
}, {
_id: 'id2',
name: 'Post2'
}, {
_id: 'id3',
name: 'Post3'
}, {
_id: 'id4',
name: 'Post4'
}]
$scope.deletePost = function(post) {
var posts = $scope.posts;
posts.splice(posts.indexOf(post), 1);
}
$scope.addPost = function() {
var posts = $scope.posts;
posts.push({
_id: 'id' + (posts.length + 1),
name: 'Post' + (posts.length + 1)
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<button ng-click="addPost()">Add</button>
<div data-ng-repeat="post in posts | orderBy:'_id':true">
<div ng-click="deletePost(post)">{{post.name}}</div>
</div>
</div>
答案 1 :(得分:1)
不要按索引删除项目,可能是您的$ scope.posts订单和呈现的订单不一样。当你使用orderBy过滤ng-repeat为渲染创建新数组时,不要重新排序$ scope.posts。
您可以按ID删除项目。它更安全。
var index;
$filter($scope.posts, function(val, key){
if(val._id === id && !index)
index = key;
})
if(index){
$scope.posts.splice(index, 1);
}
此外,如果您想首先显示插入的行,则应使用推送
的非强制代替