ng-repeat with 函数创建新对象并避免 [$rootScope:infdig]
ng-repeat with function to create new objects and avoid [$rootScope:infdig]
plunker preview
我有包含有关用户信息的主数组。
每个项目(用户)都有 'data' 个数组:
{
name: 'Linda',
data: [
{
value: 3
},
{
value: 6
}
]
}
我需要像这样打印主数组:
- 琳达 - 3
- 琳达 - 6
已更新:我可以更改输入中的名称。参见版本 2。
所以我将 ng-repeat 与 returns 新对象的函数一起使用。我得到了已知错误:[$rootScope:infdig]
为了避免这个错误,我使用 google groups 方法:'change' 过滤器和 'linker' 工厂。
(我想用 $$hashKey 的方法。但是我不明白该怎么做)
要得到这个错误,打开我的代码并删除 HTML 中的 'change' 过滤器。
问题:也许您知道更简单的打印数组的解决方案?谢谢。
如果我在打印前排序?
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.users = [
{
name: 'Linda',
data: [
{
value: 3
},
{
value: 6
}
]
},
{
name: 'John',
data: [
{
value: 2
},
{
value: 11
}
]
}
];
$scope.getUsersData = function(){
var output = [];
$scope.users.forEach(function(user){
if ('data' in user) {
user.data.forEach(function(userData){
output.push({name: user.name, value: userData.value});
});
}
});
return output;
};
});
// From https://groups.google.com/d/msg/angular/IEIQok-YkpU/iDw32-YRr3QJ
app.filter('change', function(linker) {
return function(items) {
var collection = items.map(function (item) {
return item;
});
return linker(collection, 'some-key');
};
});
app.factory('linker', function () {
var links = {};
return function (arr, key) {
var link = links[key] || [];
arr.forEach(function (newItem, index) {
var oldItem = link[index];
if (!angular.equals(oldItem, newItem))
link[index] = newItem;
});
link.length = arr.length;
return links[key] = link;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl as main">
<ul>
<li ng-repeat="user in users = getUsersData() | change track by $index">{{user.name}} - {{user.value}}</li>
</ul>
<hr>
<div ng-repeat="user in users">
<input ng-model="user.name"/>
</div>
</body>
如果您使用 track by
,Angular 不会将 $$hashKey
属性 添加到数组中的对象。 $$hashKey
是由 angular 添加的默认值 属性,用于跟踪给定 数组 中的更改。
使用 ng-repeat
而不使用 track by
以利用 hashKey
尝试这样的事情。 没有过滤器或嵌套 ng-repeat
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
var users = [{
name: 'Linda',
data: [{
value: 3
}, {
value: 6
}]
}, {
name: 'John',
data: [{
value: 2
}, {
value: 11
}]
}];
$scope.getUsersData = function() {
var output = [];
users.forEach(function(user, ind) {
if ('data' in user) {
user.data.forEach(function(userData, ind) {
output.push({
name: user.name,
value: userData.value
});
});
}
});
return output;
};
$scope.userFetchedData = $scope.getUsersData(); // here is the magic
});
app.factory('linker', function() {
var links = {};
return function(arr, key) {
var link = links[key] || [];
arr.forEach(function(newItem, index) {
var oldItem = link[index];
if (!angular.equals(oldItem, newItem))
link[index] = newItem;
});
link.length = arr.length;
return links[key] = link;
}
})
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
</head>
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="user in userFetchedData track by $index">{{user.name}} - {{user.value}}</li>
</ul>
</body>
</html>
plunker version 3
我需要在输入字段中更改 用户名。所以我认为对我来说简单快捷的解决方案是使用 $watch
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.users = [
{
name: 'Linda',
data: [
{
value: 3
},
{
value: 6
}
]
},
{
name: 'John',
data: [
{
value: 2
},
{
value: 11
}
]
}
];
$scope.$watch(function(){
return JSON.stringify($scope.users);
}, function(){
$scope.usersData = $scope.prepareUsersForPrint($scope.users);
})
$scope.prepareUsersForPrint = function(arr){
var output = [];
arr.forEach(function(user){
if ('data' in user) {
user.data.forEach(function(userData){
output.push({name: user.name, value: userData.value});
});
}
});
return output;
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl as main">
<ul>
<li ng-repeat="user in usersData track by $index">{{user.name}} - {{user.value}}</li>
</ul>
<hr>
<div ng-repeat="user in users">
<input ng-model="user.name"/>
</div>
</body>
plunker preview
我有包含有关用户信息的主数组。
每个项目(用户)都有 'data' 个数组:
{
name: 'Linda',
data: [
{
value: 3
},
{
value: 6
}
]
}
我需要像这样打印主数组:
- 琳达 - 3
- 琳达 - 6
已更新:我可以更改输入中的名称。参见版本 2。
所以我将 ng-repeat 与 returns 新对象的函数一起使用。我得到了已知错误:[$rootScope:infdig]
为了避免这个错误,我使用 google groups 方法:'change' 过滤器和 'linker' 工厂。
(我想用 $$hashKey 的方法。但是我不明白该怎么做)
要得到这个错误,打开我的代码并删除 HTML 中的 'change' 过滤器。
问题:也许您知道更简单的打印数组的解决方案?谢谢。
如果我在打印前排序?
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.users = [
{
name: 'Linda',
data: [
{
value: 3
},
{
value: 6
}
]
},
{
name: 'John',
data: [
{
value: 2
},
{
value: 11
}
]
}
];
$scope.getUsersData = function(){
var output = [];
$scope.users.forEach(function(user){
if ('data' in user) {
user.data.forEach(function(userData){
output.push({name: user.name, value: userData.value});
});
}
});
return output;
};
});
// From https://groups.google.com/d/msg/angular/IEIQok-YkpU/iDw32-YRr3QJ
app.filter('change', function(linker) {
return function(items) {
var collection = items.map(function (item) {
return item;
});
return linker(collection, 'some-key');
};
});
app.factory('linker', function () {
var links = {};
return function (arr, key) {
var link = links[key] || [];
arr.forEach(function (newItem, index) {
var oldItem = link[index];
if (!angular.equals(oldItem, newItem))
link[index] = newItem;
});
link.length = arr.length;
return links[key] = link;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl as main">
<ul>
<li ng-repeat="user in users = getUsersData() | change track by $index">{{user.name}} - {{user.value}}</li>
</ul>
<hr>
<div ng-repeat="user in users">
<input ng-model="user.name"/>
</div>
</body>
track by
,Angular 不会将 $$hashKey
属性 添加到数组中的对象。 $$hashKey
是由 angular 添加的默认值 属性,用于跟踪给定 数组 中的更改。
使用 ng-repeat
而不使用 track by
以利用 hashKey
尝试这样的事情。 没有过滤器或嵌套 ng-repeat
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
var users = [{
name: 'Linda',
data: [{
value: 3
}, {
value: 6
}]
}, {
name: 'John',
data: [{
value: 2
}, {
value: 11
}]
}];
$scope.getUsersData = function() {
var output = [];
users.forEach(function(user, ind) {
if ('data' in user) {
user.data.forEach(function(userData, ind) {
output.push({
name: user.name,
value: userData.value
});
});
}
});
return output;
};
$scope.userFetchedData = $scope.getUsersData(); // here is the magic
});
app.factory('linker', function() {
var links = {};
return function(arr, key) {
var link = links[key] || [];
arr.forEach(function(newItem, index) {
var oldItem = link[index];
if (!angular.equals(oldItem, newItem))
link[index] = newItem;
});
link.length = arr.length;
return links[key] = link;
}
})
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
</head>
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="user in userFetchedData track by $index">{{user.name}} - {{user.value}}</li>
</ul>
</body>
</html>
plunker version 3
我需要在输入字段中更改 用户名。所以我认为对我来说简单快捷的解决方案是使用 $watch
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.users = [
{
name: 'Linda',
data: [
{
value: 3
},
{
value: 6
}
]
},
{
name: 'John',
data: [
{
value: 2
},
{
value: 11
}
]
}
];
$scope.$watch(function(){
return JSON.stringify($scope.users);
}, function(){
$scope.usersData = $scope.prepareUsersForPrint($scope.users);
})
$scope.prepareUsersForPrint = function(arr){
var output = [];
arr.forEach(function(user){
if ('data' in user) {
user.data.forEach(function(userData){
output.push({name: user.name, value: userData.value});
});
}
});
return output;
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl as main">
<ul>
<li ng-repeat="user in usersData track by $index">{{user.name}} - {{user.value}}</li>
</ul>
<hr>
<div ng-repeat="user in users">
<input ng-model="user.name"/>
</div>
</body>