使用ng-repeat与Bootstrap和AngularJS的结构问题

时间:2014-03-23 14:39:44

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

我正在使用Bootstrap和AngularJS构建应用程序。在某些时候,我对col-md-3进行了ng-repeat,列出了产品。我的问题是我希望能够在网格中插入一个折叠,但是由于列是自动生成的,所以我真的不知道该怎么做。

这是一个更好地理解它的图表: 首先,从ng-repeat中填充.col-md-3的网格。

enter image description here

我想要实现的目标是添加一个.col-md-12,它出现在点击的.col-md-3行的正下方。

enter image description here

我最初的想法是在每组4 .col-md-3之后动态添加一个空的.col-md-12,但我不知道该怎么做,而且它似乎有点像这将是一个相当沉闷的方法。有什么想法吗?

这里是相关的html:

<div class="infinite" infinite-scroll="loadDetails()">
      <div class="col-xs-3 col-md-3" ng-repeat="release in main.releases | filter:main.album">
        <release release="release" artist="main.artist" class="dropdown"></release> 
      </div>
</div>

编辑:这是一个包含tasseKATT解决方案的working Plunker

2 个答案:

答案 0 :(得分:3)

在内部元素上放置一个自定义指令以及一个以1开头的位置计数器和一个描述它是否是最后一个元素的标记:

<div ng-repeat="item in items" class="col-xs-3">
  <div class="item" the-directive position="{{ $index + 1 }}" last="{{ $last }}">
  </div>
</div>

使用隔离范围创建指令,将范围属性绑定到position和last属性的值,并将click事件处理程序附加到元素:

app.directive('theDirective', function() {
  return {
    restrict: 'A',
    scope: { position: '@', last: '@' },
    link: function(scope, element, attrs) {
      element.bind('click', function() {
        ...
      });
    }
  };
});

在点击处理程序中,首先创建折叠元素,如果它已经存在,则选择它:

var collapseQuery = document.querySelector('#collapse');
var collapse = collapseQuery === null ?
angular.element('<div id="collapse" class="col-xs-12"><div class="twelve"></div></div>') :
angular.element(collapseQuery);

根据点击元素的位置计算四舍五入到最接近的四的倍数:

var calculatedPosition = Math.ceil(scope.position / 4) * 4;

如果位置超出范围,则将元素置于计算位置或最后一位:

var calculatedQuery = document.querySelector('[position="' + calculatedPosition + '"]');
if (calculatedQuery === null) calculatedQuery = document.querySelector('[last="true"]');;

var calculatedElement = angular.element(calculatedQuery);

在元素位于计算位置后插入collapse元素:

calculatedElement.parent().after(collapse);

可以使用一些优化,但希望能让你走上正确的轨道。

演示一些额外的视觉效果: http://plnkr.co/edit/fsC51vS7Ily3X3CVmxSZ?p=preview

答案 1 :(得分:1)

如果您使用12 columns per a row遵循引导程序约定,则此问题更容易以有角度的方式回答:

  

通过指定要跨越的十二个可用列的数量来创建网格列。例如,三个相等的列将使用三个.col-xs-4。

在您的情况下,这意味着每行最多可包含4个.col-xs-3列,或仅包含1 .col-xs-12个列。您可以通过将数据拆分为较小数组的数组来准备以这种方式显示的数据。

$scope.getRows = function(array) {
var rows = [];

//https://stackoverflow.com/questions/8495687/split-array-into-chunks
var i,j,temparray,chunk = 4;
for (i=0,j=array.length; i<j; i+=chunk) {
    temparray = array.slice(i,i+chunk);

    rows.push(temparray);
}

return rows;
};

$scope.rows = $scope.getRows($scope.main.releases);

然后,您可以嵌套ngRepeat以实现所需的布局,使用ng-if仅在点击相应的col-xs-12时创建.col-xs-3

<div ng-repeat="row in rows">
  <div class="row">
    <div class="col-xs-3" ng-repeat="release in row" ng-click="main.releaseClicked=release">
      <div class="release">{{release}}</div> 
    </div>
  </div>
  <div class="row" ng-repeat="release in row" ng-if="main.releaseClicked==release">
    <div class="col-xs-12">
      <div class="detail">Release detail: {{release}}</div>
    </div>
  </div>
</div>

这为您留下了更多declarative view,它描述了应用程序的工作方式,并且不需要jQuery来进行DOM操作。

这是一个有效的演示:http://plnkr.co/ujlpq5iaX413fThbocSj