AngularJS:我可以使用过滤器在ng-repeat中对数组进行分块吗?
AngularJS: Can I use a filter to chunk an array in ng-repeat?
编辑以添加一个明确的问题:我有一个一定长度的平面数组,我想把它放入 tr/td 类型的视图中?这也可能在引导网格或类似的东西中。本质上,我想在一系列长度为 n 的块中显示一个平面数组。
这个问题在SO上有很多变体,但我还没有真正看到一个很好的解释:如何使这项工作或为什么不能。所以我做了一个非常简单的例子来演示这个问题。它将呈现,但如果您检查日志,您将看到错误(太大而无法链接到)。
索引.html:
<!DOCTYPE html>
<html lang="en-US" ng-app="rowApp">
<head><title>Angular chunks</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js" integrity="sha384-c4XWi4+MS7dBmCkPfB02+p/ExOF/ZBOfD2S4KR6mkmpBOg7IM6SUpA1KYZaVr7qE" crossorigin="anonymous"></script>
<script src="app.js"></script>
</head>
<body>
<table ng-controller="rowController" border="1" style="width:30%">
<tr ng-repeat="people_chunk in people | chunk:4">
<td ng-repeat="person in people_chunk">{{person.name}}</td>
</td>
</table>
</body>
</html>
应用.js:
var rowApp = angular.module('rowApp', ['filters']);
angular.module('filters', []).
filter('chunk', function () {
return function (items, chunk_size) {
var chunks = [];
if (angular.isArray(items)) {
if (isNaN(chunk_size))
chunk_size = 4;
for (var i = 0; i < items.length; i += chunk_size) {
chunks.push(items.slice(i, i + chunk_size));
}
} else {
console.log("items is not an array: " + angular.toJson(items));
}
return chunks;
};
});
rowApp.controller('rowController',
function ($scope, $http) {
$http.get("/people.json")
.then(function(response) { $scope.people = response.data; });
});
People.json:
[{"name": "a"}, {"name": "b"}, {"name": "c"}, {"name": "d"},
{"name": "1"}, {"name": "2"}, {"name": "3"}, {"name": "4"}]
然后,您可以python -m SimpleHTTPServer 9000
提供所有这些服务,然后转到http://localhost:9000/
您可以通过简单地记住您的块函数来避免无限摘要循环。 这解决了 ng-repeat 永远找不到正确的引用并且总是认为您正在返回导致无限$digest的新项目的问题。
angular.module('filters', []).
filter('chunk', function () {
function cacheIt(func) {
var cache = {};
return function(arg, chunk_size) {
// if the function has been called with the argument
// short circuit and use cached value, otherwise call the
// cached function with the argument and save it to the cache as well then return
return cache[arg] ? cache[arg] : cache[arg] = func(arg,chunk_size);
};
}
// unchanged from your example apart from we are no longer directly returning this
function chunk(items, chunk_size) {
var chunks = [];
if (angular.isArray(items)) {
if (isNaN(chunk_size))
chunk_size = 4;
for (var i = 0; i < items.length; i += chunk_size) {
chunks.push(items.slice(i, i + chunk_size));
}
} else {
console.log("items is not an array: " + angular.toJson(items));
}
return chunks;
}
// now we return the cached or memoized version of our chunk function
// if you want to use lodash this is really easy since there is already a chunk and memoize function all above code would be removed
// this return would simply be: return _.memoize(_.chunk);
return cacheIt(chunk);
});
当过滤器以切片形式返回新的数组实例时,Angular 的ngRepeat
将检测到它们的变化(因为ngRepeat
内部使用$watchCollection
),并将导致无限摘要循环。甚至还有一个问题,但自 2013 年以来就被废弃了:https://github.com/angular/angular.js/issues/2033
如果将代码段更改为包含非常量表达式,则此问题仍然存在,例如 [[x]]
:
<div ng-repeat="a in [[x]]">
<div ng-repeat="b in a">
</div>
</div>
恐怕您将不得不将分块逻辑移动到控制器中,或者使用 css 形成一个 4 宽度的表。
也许这对某人有用,你永远不知道
以下代码将为存储数组分配一个额外的值 (store_chunk)。所以我可以使用 ng-repeat 在我的 HTML 中显示 3 个不同的列
var x = 0;
var y = 1;
var how_many_chunks = 3;
var limit = $scope.main.stores.length / how_many_chunks ;
angular.forEach($scope.main.stores, function(e, key) {
if (x <= limit) {
$scope.main.stores[key].store_chunk = y;
}
else{
y += 1;
limit = y * limit;
$scope.main.stores[key].store_chunk = y;
}
x += 1;
});
这里的 HTML
<div class="row">
<div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
<ul class="main_report">
<li ng-repeat="store in main.stores | filter:{ store_chunk: 3 }">{{store.store_name}}</li>
</ul>
</div>
<div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
<ul class="main_report">
<li ng-repeat="store in main.stores | filter:{ store_chunk: 3 }">{{store.store_name}}</li>
</ul>
</div>
<div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
<ul class="main_report">
<li ng-repeat="store in main.stores | filter:{ store_chunk: 3 }">{{store.store_name}}</li>
</ul>
</div>
</div>
这就像一个魅力! 不要仅仅因为你不喜欢它而投票反对..而是竖起大拇指!
- 有没有一种方法可以添加相同的项目val=“0”;4〃;到JavaScript中数组的每个对象
- Javascript,有没有一种方法可以将数组写成没有逗号或空格的单个文本字符串
- 是否有任何方法可以使用jQuery替换在数组中定义值的文本
- 高亮显示与数组字符串一起使用时文本插件中断
- 对一个对象使用reduce可以返回一个没有't在数组中包含目标字母
- 加入数组会使它们作为对象加入
- 为什么只有一个数字项的数组可以用一些算术运算
- 在数组中使用用波浪形括号括起来的变量
- Javascript.创建类似数组的对象.是否可以使 .length 自动增量
- 包含不同对象的数组可以
- javascript中的数组可以被删除吗?
- Ajax 请求,获取 JS 数组并使其可用
- 尝试将IF语句与数组一起使用时遇到问题
- 加入一个包含多个空格的数组可以消除Chrome中的重复空格
- 如何重新排列具有相似项的数组,使相似项永远不会彼此相邻
- 修改字符串数组,使其在targeting中用作id
- 排序javascript数组,使空白值总是在底部
- 为什么Javascript数组可以同时保存多种数据类型?
- 将对象推送到数组中,然后对其进行修改,可以使所有对象属性相同
- JavaScript 数组可以为空吗?