Angular ng-repeat每3或4个cols添加一个bootstrap行

hug*_*ugs 108 twitter-bootstrap angularjs ng-repeat angularjs-ng-repeat

我正在寻找正确的模式,每3列注入一个bootstrap行类.我需要这个,因为cols没有固定的高度(我不想修复它),所以它打破了我的设计!

这是我的代码:

<div ng-repeat="product in products">
    <div ng-if="$index % 3 == 0" class="row">
        <div class="col-sm-4" >
            ...
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

但它只在每行显示一个产品.我想要的最终结果是:

<div class="row">
    <div class="col-sm4"> ... </div>
    <div class="col-sm4"> ... </div>
    <div class="col-sm4"> ... </div>
</div>
<div class="row">
    <div class="col-sm4"> ... </div>
    <div class="col-sm4"> ... </div>
    <div class="col-sm4"> ... </div>
</div>
Run Code Online (Sandbox Code Playgroud)

我只能用ng-repeat模式(没有指令或控制器)来实现这个目的吗?本文档介绍了NG-重复启动和NG-重复-结束,但我无法弄清楚如何使用它是这种使用情况!我觉得这是我们经常在bootstrap模板中使用的东西!?谢谢

Dun*_*can 161

最有效的答案,虽然有效,但不是我认为是有角度的方式,也不是使用bootstrap自己的类来处理这种情况.正如@claies所提到的,该.clearfix课程适用于这些情况.在我看来,最干净的实施如下:

<div class="row">
    <div ng-repeat="product in products">
        <div class="clearfix" ng-if="$index % 3 == 0"></div>
        <div class="col-sm-4">
            <h2>{{product.title}}</h2>
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

这种结构避免了产品数组的混乱索引,允许使用干净的点表示法,并且将clearfix类用于其预期目的.

  • 这是一个好主意,但是如果你对使用flexbox感兴趣,你必须在行上使用它而不是行内的div,以便允许每个box/div具有相同的高度.Clearfix很棒,但没有帮助保持一切排队. (5认同)
  • 这是我的首选答案.非常干净,容易. (3认同)
  • 这是完美的答案 (3认同)

小智 148

我知道它有点晚了但它仍然可以帮助某人.我是这样做的:

<div ng-repeat="product in products" ng-if="$index % 3 == 0" class="row">
    <div class="col-xs-4">{{products[$index]}}</div>
    <div class="col-xs-4" ng-if="products.length > ($index + 1)">{{products[$index + 1]}}</div>
    <div class="col-xs-4" ng-if="products.length > ($index + 2)">{{products[$index + 2]}}</div>
</div>
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

  • 很好的解决方案,但它不会检查$ index + 1和$ index +2是否超过数组边界.最后两个div需要`ng-if ="$ index + 1 <products.length"`和`ng-if ="$ index + 2 <products.length"` (17认同)
  • 它实际上帮了我很多!! 谢谢. (3认同)

小智 24

好了,该解决方案远远比那些简单的已经在这里,并允许不同的设备宽度不同的列宽.

<div class="row">
    <div ng-repeat="image in images">
        <div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">
            ... your content here ...
        </div>
        <div class="clearfix visible-lg" ng-if="($index + 1) % 6 == 0"></div>
        <div class="clearfix visible-md" ng-if="($index + 1) % 4 == 0"></div>
        <div class="clearfix visible-sm" ng-if="($index + 1) % 3 == 0"></div>
        <div class="clearfix visible-xs" ng-if="($index + 1) % 2 == 0"></div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

请注意,该% 6部分应该等于结果列的数量.因此,如果在列元素上有类,col-lg-2那么将有6列,所以请使用... % 6.

这种技术(不包括ng-if)实际上是在这里记录的:Bootstrap docs


Cla*_*ies 17

虽然您想要实现的目标可能很有用,但我认为您可能会忽略另一种选择,这种选择要简单得多.

你是对的,当你的列不是固定的高度时,Bootstrap表会很奇怪.但是,创建了一个引导类来解决此问题并执行响应式重置.

只需<div class="clearfix"></div>在每个新行开始之前创建一个空,以允许浮动重置并使列返回到正确的位置.

这是一个bootply.


hug*_*ugs 16

谢谢你的建议,你让我走在正确的道路上!

我们来做一个完整的解释:

  • 默认情况下,AngularJS http get查询返回一个对象

  • 因此,如果您想使用@Ariel Array.prototype.chunk函数,首先要将对象转换为数组.

  • 然后在你的控制器中使用块功能,否则如果直接用于ng-repeat,它会带来infdig错误.最终的控制器看起来:

    // Initialize products to empty list
    $scope.products = [];
    
    // Load products from config file
    $resource("/json/shoppinglist.json").get(function (data_object)
    {
        // Transform object into array
        var data_array =[];
        for( var i in data_object ) {
            if (typeof data_object[i] === 'object' && data_object[i].hasOwnProperty("name")){
                data_array.push(data_object[i]);
            }
        }
        // Chunk Array and apply scope
        $scope.products = data_array.chunk(3);
    });
    
    Run Code Online (Sandbox Code Playgroud)

HTML变成:

<div class="row" ng-repeat="productrow in products">

    <div class="col-sm-4" ng-repeat="product in productrow">
Run Code Online (Sandbox Code Playgroud)

另一方面,我决定直接从我的JSON文件返回一个数组[]而不是一个对象{}.这样,控制器就变成了(请注意具体语法isArray:true):

    // Initialize products to empty list 
    $scope.products = [];

    // Load products from config file
    $resource("/json/shoppinglist.json").query({method:'GET', isArray:true}, function (data_array)
    {
        $scope.products = data_array.chunk(3);
    });
Run Code Online (Sandbox Code Playgroud)

HTML保持与上面相同.

优化

悬念中的最后一个问题是:如何使用100%AngularJS而不扩展具有块功能的javascript数组...如果有人有兴趣向我们展示ng-repeat-start和ng-repeat-end是否可行... . 我很好奇 ;)

安德鲁的解决方案

由于@Andrew,我们现在知道添加引导clearfix类每三个(或其他数字)元素从型动物块的高度修正显示问题.

所以HTML变成:

<div class="row">

    <div ng-repeat="product in products">

        <div ng-if="$index % 3 == 0" class="clearfix"></div>

        <div class="col-sm-4"> My product descrition with {{product.property}}
Run Code Online (Sandbox Code Playgroud)

并且你的控制器保持非常柔软,删除了chunck功能:

// Initialize products to empty list 
        $scope.products = [];

        // Load products from config file
        $resource("/json/shoppinglist.json").query({method:'GET', isArray:true}, function (data_array)
        {
            //$scope.products = data_array.chunk(3);
            $scope.products = data_array;
        });
Run Code Online (Sandbox Code Playgroud)


Jua*_*dán 7

基于Alpar解决方案,仅使用带有anidated ng-repeat的模板.适用于完整行和部分空行:

<div data-ng-app="" data-ng-init="products='soda','beer','water','milk','wine']" class="container">
    <div ng-repeat="product in products" ng-if="$index % 3 == 0" class="row">
        <div class="col-xs-4" 
            ng-repeat="product in products.slice($index, ($index+3 > products.length ? 
            products.length : $index+3))"> {{product}}</div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

的jsfiddle


Ari*_*son 6

你可以在没有指令的情况下完成,但我不确定这是最好的方法.为此,您必须从要在表中显示的数据创建数组数组,然后使用2 ng-repeat来遍历数组.

创建显示数组使用此函数就像products.chunk(3)

Array.prototype.chunk = function(chunkSize) {
    var array=this;
    return [].concat.apply([],
        array.map(function(elem,i) {
            return i%chunkSize ? [] : [array.slice(i,i+chunkSize)];
        })
    );
}
Run Code Online (Sandbox Code Playgroud)

然后使用2 ng-repeat做类似的事情

<div class="row" ng-repeat="row in products.chunk(3)">
  <div class="col-sm4" ng-repeat="item in row">
    {{item}}
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)


wat*_*aru 5

我刚刚制作了一个仅在模板中工作的解决方案.解决方案是

    <span ng-repeat="gettingParentIndex in products">
        <div class="row" ng-if="$index<products.length/2+1">    <!-- 2 columns -->
            <span ng-repeat="product in products">
                <div class="col-sm-6" ng-if="$index>=2*$parent.$index && $index <= 2*($parent.$index+1)-1"> <!-- 2 columns -->
                    {{product.foo}}
                </div>
            </span>
        </div>
    </span>
Run Code Online (Sandbox Code Playgroud)

Point正在使用两次数据,一次是外部循环.额外的跨度标签将保留,但这取决于您的权衡方式.

如果它是一个3列布局,它就会像

    <span ng-repeat="gettingParentIndex in products">
        <div class="row" ng-if="$index<products.length/3+1">    <!-- 3 columns -->
            <span ng-repeat="product in products">
                <div class="col-sm-4" ng-if="$index>=3*$parent.$index && $index <= 3*($parent.$index+1)-1"> <!-- 3 columns -->
                    {{product.foo}}
                </div>
            </span>
        </div>
    </span>
Run Code Online (Sandbox Code Playgroud)

老实说我想要

$index<Math.ceil(products.length/3)
Run Code Online (Sandbox Code Playgroud)

虽然没有用.


McG*_*gen 5

关于@Duncan答案的另一个小改进和基于clearfix元素的其他答案.如果要使内容可单击,则需要z-index> 0或clearfix将重叠内容并处理单击.

这是不起作用示例(您无法看到光标指针并且单击将不执行任何操作):

<div class="row">
    <div ng-repeat="product in products">
        <div class="clearfix" ng-if="$index % 3 == 0"></div>
        <div class="col-sm-4" style="cursor: pointer" ng-click="doSomething()">
            <h2>{{product.title}}</h2>
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

虽然这是固定的:

<div class="row">
    <div ng-repeat-start="product in products" class="clearfix" ng-if="$index % 3 == 0"></div>
    <div ng-repeat-end class="col-sm-4" style="cursor: pointer; z-index: 1" ng-click="doSomething()">
            <h2>{{product.title}}</h2>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

我添加z-index: 1了内容提高了clearfix,我已经删除了容器div代替ng-repeat-startng-repeat-end(可从AngularJS 1.2获得),因为它使z-index无法正常工作.

希望这可以帮助!

更新

Plunker:http://plnkr.co/edit/4w5wZj