2013-03-08 63 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