如何在ng-repeat中添加多个ng-repeats?

时间:2017-03-04 07:39:13

标签: javascript angularjs twitter-bootstrap css3 angularjs-ng-repeat

好的,我在这里需要一些具有挑战性的网格,需要一些帮助。 我需要找到一种通过ng-repeat填充数据的方法。我将附上我想要实现的网格布局的图像,并且应该填充数据的顺序。我已经使用以下方法在HTML中完成了布局。但是无法通过ng-repeat找到一种方法。

ROW 1 - 正常bootstrap col-md-4和col-md-8

第2行 - 我使用CSS3 Flexbox完成了这一行。你可以看看下面的代码。

ROW 3 - 正常bootstrap col-md-4和col-md-8

enter image description here

This是我一直想做的事情的吸引人。 [https://plnkr.co/edit/NtXEnQcKpM0JxnLsxc4m?p=preview] 2

我也会尝试传达这背后的逻辑。 因此,在网格的底部将有一个加载更多按钮,以再次重复整个布局并填充数据。因此我计划在容器上放置和重复ng-repeat。在此之后,我将布局划分为3行。 - 第一个由第1列和第2列组成 - 第二行由第3列到第7列组成 - 第三行由第8列和第9列组成

返回的数组也以相同的方式划分。

我希望如果我对此的处理方法不对,并且可能需要解决这个问题,我会明白这一点。

2 个答案:

答案 0 :(得分:2)

为了进行您概述的设计,我建议您执行以下操作:

  1. 使用过滤器将文章“分块”为9个组(类似于此memoized chunking solution

  2. 使用自定义指令创建“模板”

  3. 利用响应式固定比率网格系统(如咳嗽我的图书馆Perfect Bootstrap 咳嗽

  4. <强> Example JSFiddle

    步骤1

    让我们将您的JSON放回标准数组中,然后在运行时将其“分块”为9批。我们创建一个角度filter然后使用| chunk应用。为了避免无限的摘要循环,我们需要使用变量来记忆函数的结果,在下面的代码中我们使用字符串'newsGroups'。如果您打算在阵列中加载更多项目,比如无限滚动,则需要更新此变量以刷新记忆结果。把它想象成一个缓存。

    为简洁起见,我已将您的文章数组剥离为每个元素的idtitle项。我认为无论如何这都是来自开发环境中的AJAX调用。

    <强> HTML

    <div class="container-fluid" ng-controller="MyCtrl">
      <div class="template-container" ng-repeat="newsGroup in NewsListing | chunk:'newsGroups'">
        <!-- content here -->
      </div>
    </div>
    

    JS Chunk过滤器和基本文章

    var myApp = angular.module('myApp', []);
    myApp.filter('chunk', function() {
      function cacheIt(func) {
        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 = 9;
          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);
    });
    myApp.controller('MyCtrl', function($scope) {
      $scope.NewsListing = [{
        "id": "71b85130-ffe4-11e6-81a4-c1bd97df0d2d",
        "title": "Exercitation ullamco laboris"
      }, {
        "id": "58847180-ffe4-11e6-81a4-c1bd97df0d2d",
        "title": "Duis aute irure dolor in reprehenderit"
      }, {
        "id": "35d2c290-ffe4-11e6-81a4-c1bd97df0d2d",
        "title": "Ut enim ad minim"
      }, {
        "id": "fdbdeb00-ffe3-11e6-81a4-c1bd97df0d2d",
        "title": "Ut enim ad minim"
      }, {
        "id": "df858f30-ffe3-11e6-81a4-c1bd97df0d2d",
        "title": "Dolore magna aliqua"
      }, {
        "id": "bbc619c0-ffe3-11e6-81a4-c1bd97df0d2d",
        "title": "Qui officia deserunt mollit anim"
      }, {
        "id": "8467e800-ffe3-11e6-81a4-c1bd97df0d2d",
        "title": "Consectetur adipisicing elit, sed do eiusm"
      }, {
        "id": "5aea9180-ffe3-11e6-81a4-c1bd97df0d2d",
        "title": "Lorem elit, sed do eiusm"
      }, {
        "id": "418d09c0-ffe3-11e6-81a4-c1bd97df0d2d",
        "title": "ALL YOU NEED TO KNOW ABOUT WAREHOUSE"
      }, {
        "id": "71b85130-ffe4-11e6-81a4-c1bd97df0d2e",
        "title": "Exercitation ullamco laboris2"
      }, {
        "id": "58847180-ffe4-11e6-81a4-c1bd97df0d2e",
        "title": "Duis aute irure dolor in reprehenderit2"
      }, {
        "id": "35d2c290-ffe4-11e6-81a4-c1bd97df0d2e",
        "title": "Ut enim ad minim2"
      }, {
        "id": "fdbdeb00-ffe3-11e6-81a4-c1bd97df0d2e",
        "title": "Ut enim ad minim2"
      }, {
        "id": "df858f30-ffe3-11e6-81a4-c1bd97df0d2e",
        "title": "Dolore magna aliqua2"
      }, {
        "id": "bbc619c0-ffe3-11e6-81a4-c1bd97df0d2e",
        "title": "Qui officia deserunt mollit anim2"
      }, {
        "id": "8467e800-ffe3-11e6-81a4-c1bd97df0d2e",
        "title": "Consectetur adipisicing elit, sed do eiusm2"
      }, {
        "id": "5aea9180-ffe3-11e6-81a4-c1bd97df0d2e",
        "title": "Lorem elit, sed do eiusm2"
      }, {
        "id": "418d09c0-ffe3-11e6-81a4-c1bd97df0d2e",
        "title": "ALL YOU NEED TO KNOW ABOUT WAREHOUSE2"
      }];
    })
    

    第2步

    在步骤1中HTML的content here评论部分,我们将应用自定义指令。在现实生活中,我可能会使用一个单独的文件来保存模板,但是,对于js小提琴的约束,我需要将其定义为text/ng-template script标记。

    您可以看到步骤1中newsGroup的{​​{1}}将使用范围值ng-repeat传递给我们的自定义指令。这将包含最多9篇新闻文章。

    HTML指令调用

    items

    JS指令定义

    <div nine-item-news items="newsGroup"></div>
    

    HTML模板

    myApp.directive('nineItemNews', function() {
      return {
        restrict: 'A',
        replace: true,
        templateUrl: '/nine-item-news-template.html',
        scope: {
          items: '='
        }
      }
    });
    

    第3步

    不久前,我开发了一个CSS库,旨在提供响应灵活的固定比率网格元素。这个问题促使我最终公之于众。可以把它想象成bootstrap的水平<script type="text/ng-template" id="/nine-item-news-template.html"> <div class="template"> <!-- template content here --> </div> </script> 功能,但是垂直。

    我们将上面的col-注释替换为以下html,该html将加载来自步骤2的自定义指令传递给它的项目。我建议您展开此模板以添加template content here语句加载/卸载块,类似地,我建议使用ng-if来适应你没有提交完整9项的案例的设计(即如果只传递了6篇文章它会是什么样子)。或者,使用基于ng-class的{​​{1}}并加载完全不同的模板也可以同样有效。

    额外的CSS是添加背景颜色并删除引导列的默认填充/边距。

    注意:请注意,为了使元素保持比例,他们的ng-switch设置为items.length。当项目具有背景图像时,这尤其有效,但可能会对文本产生意想不到的后果。我的例子包括一个移动响应模板设计,它创建了比例为2:1的部分。我鼓励您仔细测试这个特定的构建和许多屏幕分辨率。

    HTML模板内容

    overflow

    <强> CSS

    hidden

答案 1 :(得分:0)

我认为在Angular中执行此操作的正确方法应该是自定义指令。

当用户更多时,应该再次出现一个内部布局,因此该指令应该显示整个布局。

你只需要将参数中的数据提供给指令,然后根据需要显示它(比如在数组中提供数据或者获取索引)。

让我们称之为指令layoutDirective。

然后你把它放在你的HTML中:

<div ng-repeat="array in arrays" ng-if="$index < limitDisplay">
  <layout-directive data=array> </layout-directive>
</div>

这里唯一的技巧是ng-if指令

当有人按下loadMore时,limitDisplay是一个int递增的位置 我不确定这样写的数据绑定,我会稍后改进我的答案来帮助你创建一个好的指令