AngularJS:我可以使用过滤器在ng-repeat中对数组进行分块吗? [英] AngularJS: Can I use a filter to chunk an array in ng-repeat?

查看:70
本文介绍了AngularJS:我可以使用过滤器在ng-repeat中对数组进行分块吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑以添加一个明确的问题:我有一个长度有限的平面数组,我想把它放到tr / td类型的视图中?这也可能在引导网格或类似的东西中。基本上我想在一系列长度为n的块中显示一个平面数组。

Edit to add a clear question: I have a flat array of some length and I want to put it into a tr/td type view? This might also be in a bootstrap grid or something like that. Essentially I want to display a flat array in a series of length-n chunks.

这个问题有很多变种,但是我还没有看到对两者的一个很好的解释:如何使这项工作或为什么它不能。所以我制作了一个非常简单示例来演示这个问题。它会渲染,但如果你检查日志,你会看到错误(太大而无法链接)。

There are a number of variations of this question on SO but I haven't really seen a good explanation of either: how to make this work or why it can't. So I've made an extremely simple example that demonstrates the problem. It will render, but if you check the logs you'll see errors (which are too large to link to).

index.html:

index.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>

app.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:

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 /

You can then serve all this with python -m SimpleHTTPServer 9000 and then go to http://localhost:9000/

推荐答案

你可以避免通过简单地记忆你的块函数来实现无限的摘要循环。这解决了ng-repeat从未找到正确引用的问题,并且总是认为你正在返回导致无限$ digest的新项目。

You can avoid an infinite digest loop by simply memoizing your chunk function. This solves the issue of ng-repeat never finding the proper references and always thinking you are returning new items causing the infinite $digest.

angular.module('filters', []).
  filter('chunk', function () {
​
    function cacheIt(func) {
      var cache = {};
      return function(arg) {
        // 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);
      };
    }

    // 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);
  });

这篇关于AngularJS:我可以使用过滤器在ng-repeat中对数组进行分块吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆