【问题标题】:How would I use AngularJS ng-repeat with Twitter Bootstrap's scaffolding?我如何将 AngularJS ng-repeat 与 Twitter Bootstrap 的脚手架一起使用?
【发布时间】:2012-06-18 21:16:25
【问题描述】:

如何使用 AngularJS ng-repeat 显示以下 HTML(Twitter Bootstrap Scaffolding)?基本上,每隔三条记录我需要关闭</div>,打印一个<hr>,然后打开另一个<div class="span4">

    <div class="row">
      <div class="span4">
        <h3>
          Project A
        </h3>
      </div>
      <div class="span4">
        <h3>
          Project B
        </h3>
      </div>
      <div class="span4">
        <h3>
          Project C
        </h3>
      </div>
    </div>

    <hr>

    <div class="row">
      <div class="span4">
        <h3>
          Project D
        </h3>
      </div>
      <div class="span4">
        <h3>
          Lab Title
        </h3>
      </div>
      <div class="span4">
        <h3>
          Project E
        </h3>
      </div>
    </div>

我为代码演示创建了一个小提琴。
http://jsfiddle.net/ADukg/261/

【问题讨论】:

    标签: twitter-bootstrap angularjs


    【解决方案1】:

    这是一种方法:

    <div ng-controller="MyCtrl">
      <div ng-repeat="project in projects">
        <span ng-if="$index % 3 == 0">
          <hr />
          <div class="row">
            <h3 class="span4" ng-if="projects[$index+0]">{{projects[$index+0]}}</h3>
            <h3 class="span4" ng-if="projects[$index+1]">{{projects[$index+1]}}</h3>
            <h3 class="span4" ng-if="projects[$index+2]">{{projects[$index+2]}}</h3>
          </div>
        </span>
      </div>
    </div>
    

    如果您有例如 7 个数据项,这种方式也可以工作:在最后 3 个数据上,它只会显示第 7 项,而不尝试显示不存在的第 8 项和第 9 项。

    http://jsfiddle.net/4LhN9/68/

    编辑:更新为使用 ng-if & angular 1.2.12

    【讨论】:

    • 这实际上是一个非常聪明的解决方案。但是你将如何处理数据集长度不能被 3 整除的情况呢?例如,假设您正在显示图像...最后一行的 $index+0 指向一个 img url,但 +1 和 +2 为空。
    • 想通了。只需在 img 上执行 ng-show="!(($index+x)>(art.length-1))" ,其中 x 分别为 0、1、2。 Angular 太灵巧了。
    • 这太棒了。 @andy 将 rob 的 ng-show 想法添加到您的小提琴中!
    • 非常有创意的方式来解决这个问题。但是,此方法在尝试使用过滤器时会中断,从而导致完全出乎意料的结果。示例:jsfiddle.net/J2CTu
    • 分叉和简化,没有多个跨度jsfiddle.net/ivarprudnikov/mSwSW
    【解决方案2】:

    the more easy answer 继续。我不喜欢原来的解决方案,因为它产生了空的 dom 元素。这是每行 3 个 div。

    <div ng-controller="ModulesCtrl">
        <div class="row" ng-repeat="i in fields.range()">
            <div class="span4" ng-repeat="field in fields.slice(i,i+3)">
                <h2>{{field}}</h2>
            </div>
        </div>
    </div>
    

    在函数FieldsCtrl($scope)中:

    $scope.fields.range = function() {
        var range = [];
        for( var i = 0; i < $scope.fields.length; i = i + 3 )
            range.push(i);
        return range;
    }
    

    如果您知道 fields.length,则可以使用 [0,3,6,9] 等代替 fields.range()

    【讨论】:

      【解决方案3】:

      更优雅的方式是使用视图模型提供分块集合,然后让视图处理它

      <div ng-controller="Controller">
          Projects <input ng-model="projects"></input>
          <hr/>
          <div ng-repeat="row in rows">
              <div ng-repeat="project in row">
                  Projects {{project}}
              </div>
              <hr/>
          </div>
      </div>​
      

      coffeescript 非常简单

      # Break up an array into even sized chunks.
      chunk = (a,s)->
          if a.length == 0
              []
          else               
              ( a[i..i+s-1] for i in [0..a.length - 1 ] by s)
      
      @Controller = ($scope)->
          $scope.projects = "ABCDEF"
      
          $scope.$watch "projects", ->      
             $scope.rows = chunk $scope.projects.split(""), 3
      
      angular.bootstrap(document, []);
      

      http://jsfiddle.net/ADukg/370/

      【讨论】:

        【解决方案4】:

        要将视图逻辑排除在控制器之外并获得更可重用的解决方案,您可以创建一个自定义过滤器,将数组拆分为行组:

        angular.module('app').filter('group', function() {
            /**
             * splits an array into groups of the given size
             * e.g. ([1, 2, 3, 4, 5], 2) -> [[1, 2], [3, 4], [5]]
             */
            return function(array, groupSize) {
                return _.groupBy(array, function(val, index) {
                    return Math.floor(index / groupSize);
                });
            };
        });
        

        在视图中:

        <div class="row" ng-repeat="group in projects | group:3">
           <div class="span4" ng-repeat="project in group">
              {{project}}
           </div>
        </div>
        

        要包含 hr,您可以使用 ng-repeat 起点和终点:

        <div class="row" ng-repeat-start="group in projects | group:3">
           <div class="span4" ng-repeat="project in group">
              {{project}}
           </div>
        </div>
        <hr ng-repeat-end />
        

        【讨论】:

        • 理论上我喜欢这个。但实际上,它会引发 10 $digest() iterations reached 异常。 See this fiddle.
        • 感谢 roufamatic。我查看了它,发现 ng-repeat 使用 $watchCollection 来检查更改。由于 $watchCollection 对数组内容进行了浅层比较,并且我的“组”过滤器每次调用时都会返回一组新数组,因此 Angular 认为数组在不断变化。一种解决方法是在 ng-repeat 之前初始化分组数组,而不是使用过滤器,使用 ng-init 或在控制器中。但随后它就失去了优雅。
        【解决方案5】:

        ng-repeat-start and ng-repeat-end end points 似乎是实现此目的的便捷方法:

        这导致了简单的代码

        <div ng-controller="MyCtrl">
            <div ng-repeat-start="project in projects">
                <span>
                    <div class="row">
                        <h3 class="span4">{{project}}</h3>
                    </div
                </span>
            </div>
            <hr ng-repeat-end ng-if="($index + 1) % 3 == 0" />
        </div>
        

        看到这个jsfiddle

        【讨论】:

          猜你喜欢
          • 2023-03-06
          • 2013-04-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多