我试图用angularjs 1.2.15建立一个分页指令:
这是我的观点:
<input type="text" ng-model="filter.user">
<input type="number" ng-model="filter.limit" ng-init="filter.limit=5">
<ul>
<li ng-repeat="user in (filteredUsers = (users | orderBy:order:reverse | filter:filter.user ) | limitTo: filter.limit)" ng-click="showDetails(user)">
{{user.id}} / {{user.firstname}} {{user.lastname}}
</li>
</ul>
<div pagination data='filteredUsers' limit='filter.limit'></div>
这是我的分页指令:
app.directive('pagination', function(){
return {
restrict: 'A',
templateUrl: 'partials/pagination.html',
scope: {
data: '=data',
limit: '=limit'
}
}
})
没有分页指令,一切都很好。但是,一旦我加载页面,我的新指令就会出现$rootScope:infdig
错误,我不明白,因为该指令没有做任何事情来操纵可能最终无限循环的数据。 />
这里有什么问题,我该如何解决?谢谢!
更新
这是控制器和资源
控制器:
usersModule.controller('usersController',
function ($scope, Users) {
function init(){
$scope.users = Users.get();
}
init();
})
资源(将用户从REST API中作为数组获取):
app.factory('Users', function($resource) {
return $resource('http://myrestapi.tld/users', null,{
'get': { method:'GET', isArray: true, cache: true }
});
});
更新2
以下是演示:http://plnkr.co/edit/9GCE3Kzf21a7l10GFPmy?p=preview
只需在左侧输入中输入一个字母(例如&#34; f&#34;)。
答案 0 :(得分:28)
问题不在指令范围内,它在指令创建的$ watch范围内。 将filteredUsers发送到指令时,该指令将创建以下行:
$scope.$watch("filteredUsers", function() {
// Directive Code...
});
请注意以下示例中我们如何在没有指令的情况下重现它: http://plnkr.co/edit/uRj19PyXkvnLNyh5iY0j
之所以发生这种情况,是因为每次摘要运行时都会更改filteredUsers(因为您将赋值放在ng-repeat语句中)。
要解决此问题,您可以考虑使用$ watch的额外参数'true'来观察和过滤控制器中的数组:
$scope.$watch("users | orderBy:order:reverse | filter:filter.user", function(newVal) {
$scope.filteredUsers = newVal;
}, true);
您可以在此处查看解决方案: http://plnkr.co/edit/stxqBtzLsGEXmsrv3Gp6
没有额外参数的$ watch(true)将对该对象进行简单比较,并且由于您在每个摘要循环中创建一个新数组,因此该对象将始终不同。 当您将true参数传递给$ watch函数时,这意味着它将实际与再次运行$ watch之前返回的对象进行深度比较,因此即使您有不同的数组实例具有相同的数据,它也会认为他们是平等的。
答案 1 :(得分:0)
快速解决方法是在指令中添加“手动”$watchCollection
,而不是双向绑定。
app.directive('pagination', function($parse){
return {
restrict: 'A',
template: '',
scope: {
limit: '=limit'
},
link: function(scope, elem, attrs) {
var dataExpr = $parse(attrs.data);
var deregister = scope.$parent.$watchCollection(dataExpr, function(val) {
scope.data = val;
});
scope.$on('$destroy', deregister);
}
}
})
$watchCollection
监视数组的内容,而不是对它的引用。
看到它正在运行here。
一般来说,我不喜欢这样的表达方式:
filteredUsers = (users | orderBy:order:reverse | filter:filter.user )
内部观点。视图应该只呈现$scope
属性,而不是创建新属性。
答案 2 :(得分:-1)
可能会删除此错误以清除浏览器历史记录设置。我有同样的问题,并应用许多解决方案来解决这个问题,但无法解决。 但是,当我删除浏览器历史记录和缓存时,此问题已解决。愿这对你有所帮助。