2013-03-08 86 views
1

我想使用twitter Bootstrap与我的应用程序由AngularJS提供动力。我开始与网格布局使用脚手架http://twitter.github.com/bootstrap/scaffolding.html#gridSystem碰上以下问题:Twitter Bootstrap脚手架与AngularJS

据对引导文档和例子,网格布局遵循这种结构:

<div class="row"> 
    <div class="span4">...</div> 
    <div class="span8">...</div> 
</div> 
<div class="row"> 
    <div class="span4">...</div> 
    <div class="span8">...</div> 
</div> 

...

意味着具有'span'类(列)的标签必须是具有'row'类(行)的标签的子元素。

在我的应用程序中,我有一个普通的对象数组 - 项目,我想在每一行中显示为3个项目。 Offcourse我不知道我将要展示的项目数量。 据我所知,这种结构需要两个嵌套循环 - 一个用于行,一个用于列,如果我的模型是二维数组,但我不想将我的模型(项目)更改为适合风景。我最终做的是使用过滤器将模型更改为二维数组,然后使用嵌套的ngRepeat创建列:http://jsfiddle.net/oburakevych/h4puc/11/

它似乎按预期工作,但在调试控制台中出现错误:

Error: 10 $digest() iterations reached. Aborting! 

从我的理解中,嵌套的ng-repeat的摘要是触发外部ng-repeat的摘要?任何人都可以提出一个正确的方式来实现这?

回答

3

这里的问题是,当您使用ng-repeat Angular为列表表达式创建监视时,该列表表达式是项目数组和过滤器的组合。当Angular运行一个摘要时,它会一直调用该表,直到表达式的值不再发生变化。而且由于你的过滤器总是创建一个新的数组,所以每次调用它的值都会发生变化,而且Angular会陷入无限循环。所以,你的代码是基本相同,这样做:

$scope.myList = []; 
$scope.$watch('myList', function() { 
    $scope.myList = []; 
}); 

随着范围的手表,你可以告诉角度通过值而不是引用进行比较,以避免无休止的消化问题,像这样的:

$scope.myList = []; 
$scope.$watch('myList', function() { 
    $scope.myList = []; 
}, true); // Passing true as the last argument triggers comparison by value instead 

但这不可能在你的情况。

<!doctype html> 
<html ng-app="myApp"> 
<head> 
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script> 
    <script> 
    angular.module('myApp', []).controller('Ctrl', function($scope) { 
     $scope.projects = [ 
      {name: 'My Project 1'}, 
      {name: 'My Project 2'}, 
      {name: 'My Project 3'}, 
      {name: 'My Project 4'}, 
      {name: 'My Project 5'}, 
      {name: 'My Project 6'} 
     ]; 

     var splitIntoRows = function(array, columns) { 
      if (array.length <= columns) { 
       return [array]; 
      } 

      var rowsNum = Math.ceil(array.length/columns); 

      var rowsArray = new Array(rowsNum); 

      for (var i = 0; i < rowsNum; i++) { 
       var columnsArray = new Array(columns); 
       for (j = 0; j < columns; j++) { 
        var index = i * columns + j; 

        if (index < array.length) { 
         columnsArray[j] = array[index]; 
        } else { 
         break; 
        } 
       } 

       rowsArray[i] = columnsArray; 
      } 

      return rowsArray; 
     } 

     $scope.$watch('projects', function() { 
      $scope.projectRows = splitIntoRows($scope.projects, 3); 
     }); 
    }); 
    </script> 
</head> 
<body ng-controller="Ctrl"> 
    <ul class="row" ng-repeat="projectRow in projectRows"> 
     <li class="span4" ng-repeat="project in projectRow"> 
      {{project.name}} 
     </li> 
    </ul> 
</body> 
</html> 

如果你仍然想使用此过滤器,你就必须实现过滤器内部缓存,使:所以在需要的时候,这样的事情你最好的赌注对此只拆分项目阵列分成更小的数组当使用相同的参数调用过滤器时,确保始终返回相同的数组引用。但这是一个滑坡,因为您需要使缓存无效以避免内存泄漏。

+0

这工作正常,谢谢! – 2013-03-10 01:46:56