列出每行2个元素的最佳方式是按角度重复ng

Best way to list 2 elements per row with ng-repeat in angular?

本文关键字:ng 方式 最佳 2个 元素      更新时间:2023-09-26

我有一个对象数组,我想使用ng repeat为每行显示2个。

我想出的解决方案如下:

 <div ng-repeat="element in elements">
      <div layout="row" ng-if="$even">
        <div flex>
          <span>{{ elements[$index].name }}</span>
        </div>
        <div flex>
          <span>{{ elements[$index+1].name }}</span>     
        </div>
      </div>
</div>

问题是,这样我就无法以正确的方式用| filter过滤内容,因为它会显示过滤后的元素和下面的元素。

解决这个问题的最佳方法是什么?

抱歉我英语不好,这不是我的第一语言。提前谢谢。

正如@Joshua Ohana在评论中所说,一个好的解决方案是预处理您的数组,然后使用您的解决方案。

根据您的解决方案,一个快速而肮脏的选项(无需预处理)是过滤span元素内的数组:

<div ng-repeat="element in elements">
  <div layout="row" ng-if="$even">
    <div flex>
      <span>{{ (elements | filter:<yourFilterHere>)[$index].name }}</span>
    </div>
    <div flex>
      <span>{{ (elements | filter:<yourFilterHere>)[$index+1].name }}</span>     
    </div>
  </div>
</div>

但我更喜欢预处理选项。

我认为,与其试图在每个ng重复中显示两个元素,不如尝试找到一种方法,在不增加额外复杂性的情况下实现相同的结果。你可以这样做:

<div ng-repeat="element in elements | filter">      
  <div layout="row" ng-if="$even">
    <div flex>
      <span>{{ element.name }}</span>
    </div>
  </div>
  <div flex ng-if="$odd">
    <span>{{ element.name }}</span>     
  </div>
</div>

我刚开始使用AngularJS大约两周,但我没能得到这个问题的确切答案。所以我决定解决自己的问题,这就是我的想法。

下面是两个筛选器,nRange返回一个数组,该数组包含一个按n递增的序列,该序列受numItems-numItems%n的限制。其中range,返回从0开始的线性序列的数组。对于下面的AngularJS代码,过滤器可以被认为是辅助函数。

/*
    Pre: [] | nRange:numItems:n
    Post:
        Ex.1:   [] | nRange:5:2 --> [0,2,4]
        Ex.1:   [] | nRange:5:3 --> [0,3]
 */
website.filter('nRange', function() {
  return function(input, numItems, n) {
    if(numItems == 0) {
        return null;
    }
    range = numItems - numItems%n;
    for(i = 0; i <= range-n; i += n) {
        input.push(i);
    }
    if(numItems%n != 0) {
        input.push(range);
    }
    return input;
  };
});
/*
    Pre: [] | range:numItems
    Post:
        Ex.1:   [] | range:5 --> [0,1,2,3,4]
        Ex.1:   [] | range:2 --> [0,1]
 */
website.filter('range', function() {
  return function(input, numItems) {
    for (var i=0; i<=numItems; i++) {
      input.push(i);
    }
    return input;
  };
});

$scope包含项目和每行projectCols的项目数。通过定义projectCols,我们可以快速轻松地更改布局。

<div class="container">
    <div class="row" ng-repeat="i in [] | nRange:projects.length:projectCols">
        <div class="col-md-{{12/projectCols}} col-sm-12 col-xs-12" ng-repeat="j in [] | range:projectCols-1">
            <project-item ng-if="projects[i+j]" info="projects[i+j]"></project-item>
        </div>
    </div>
</div>

以下HTML使用筛选器来用项目项填充。该代码所做的是,它使用nRange计数一定的量,换句话说,它就像一个for循环,其中i+=n用于增量。然后范围提供子范围,总的来说,它可以被认为如下:

for(i = 0; i < nRange; i+=n) {
    for(j = 0; i < range; i++) {
        if($scope.projects[i+j]) { // If the project exist
            // Display it in the view
        }
    }
}

所有这些都允许每行有2个、3个、4个或6个项目。

我还创建了一些css类,以正确显示项目。

.project {
    border: 1px solid gray;
    border-radius: 5px;
    background: whitesmoke;
}
.col-md-6 .project {
    margin: 30px;
    padding: 30px;
    height: 450px;
}
.col-md-4 .project {
    margin: 20px;
    padding: 20px;
    height: 400px;
}
.col-md-3 .project {
    margin: 10px;
    padding: 10px;
    height: 400px;
}
.col-md-2 .project {
    margin: 5px;
    padding: 5px;
    height: 400px;
}

这是我的网站存储库,其中包含我的完整实现。

https://github.com/arjo1203/website

这是一个现场演示!http://www.jraraujo.com/

我会使用ng repeat在无序列表中显示单个列表项,然后使用CSS将每个li的样式设置为容器宽度的50%(或者49%通常更一致),并使每个li成为内联块样式,以便它们在一行上浮动两个。

我现在在Angular4中工作,所以我不能切换到Angular1.x代码,但这里有一个纯HTML的模型,你可以测试它,然后如果它看起来像是我们问题的解决方案,则相应地修改你的代码。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
  <link rel="stylesheet" href="./arraylist.css">
</head>
<body>
<ul class="array-list">
    <li>One Item</li>
    <li>Two Item</li>
    <li>Three Item</li>
    <li>Four Item</li>
    <li>Five Item</li>
    <li>Six Item</li>
    <li>Seven Item</li>
    <li>Eight Item</li>
</ul>
</body>
</html>

和数组list.css文件:

ul.array-list {
    display: block;
    margin: 0;
    padding: 0;
}
li {
    display: inline-block;
    width: 49%;
}

你的Angular代码看起来像这样:

<div ng-repeat="element in elements">
      <ul class="array-list">
        <li>
          {{ elements[$index].name }}
        </li>
      </ul>
</div>

这并没有实现我所假设的暗/浅灰色行条纹,但你可能会找到一种方式来设计它,或者如果这不是特别重要的话,就不设计它。

这里重要的是,因为你在重复单个元素,所以当你过滤掉一些元素时,下面的元素会自动回流以填补空白,你不会因为与它们配对的元素与过滤器匹配而导致某些值的显示而得到不一致的UI。

可以使用CSS:

<div layout="row" style="flex-wrap:wrap;">
  <div layout="column" flex="50" ng-repeat="element in elements">
    <span>{{ elements.name }}</span>
  </div>
</div>