13

私はangular.jsと(議論のために)ブートストラップを使用しています。今、私は「もの」を繰り返して、それらを「行」に表示する必要があります:

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

さて、どうすれば.row角度を使って3つおきにdivを閉じることができますか?私はangular-uiからui-ifを試しましたが、それでもうまくいきません。

サーバーサイドレンダリングを使用する場合は、次のようにします(ここでは、JSP構文ですが、重要ではありません)。

<div class="row>
  <c:forEach items="${things}" var="thing" varStatus="i">
    <div class="span4">
        ..
    </div>
  <%-- Here is the trick:--%>
  <c:if test="${i.index % 3 == 2}">
          </div><div class="row">
  </c:if>
  </c:forEach>
</div>

ここでは、cssを非表示にする要素だけでなく、実際にDOMを変更する必要があることに注意してください。.row.span4divで繰り返し試してみましたが、役に立ちませんでした。

4

3 に答える 3

19

2013年11月12日編集

1.2では角度が少し変わっただけでなく、もっと良い方法があるようです。2つのフィルターを作成しました。それらを1つに結合しようとしましたが、ダイジェストエラーが発生しました。2つのフィルターは次のとおりです。

.filter("mySecondFilter", function(){
    return function(input, row, numColumns){
        var returnArray = [];
        for(var x = row * numColumns; x < row * numColumns + numColumns; x++){
            if(x < input.length){
                returnArray.push(input[x]);                    
            }
            else{
                returnArray.push(""); //this is used for the empty cells
            }
        }
        return returnArray;   
    }
})
.filter("myFilter", function(){
    return function(input, numColumns){
        var filtered = [];
        for(var x = 0; x < input.length; x++){
            if(x % numColumns === 0){
                filtered.push(filtered.length);
            }
        }
        return filtered;
    }
});

そして今、htmlは次のようになります:

<table border="1">
     <tr data-ng-repeat="rows in (objects | myFilter:numColumns)">
          <td data-ng-repeat="column in (objects | mySecondFilter:rows:numColumns)">{{ column.entry }}</td>
     </tr>  
</table>

jsFiddle: http: //jsfiddle.net/W39Q2/


2013年9月20日編集

動的列を必要とする大量のデータを処理しているときに、より良い方法を考え出しました。

HTML:

<table border="1">
    <tr data-ng-repeat="object in (objects | myFilter:numColumns.length)">
        <td data-ng-repeat="column in numColumns">{{ objects[$parent.$index * numColumns.length + $index].entry }}</td>
    </tr>  
</table>

Javascript:

$scope.objects = [ ];
for(var x = 65; x < 91; x++){
    $scope.objects.push({
        entry: String.fromCharCode(x)
    });
}

$scope.numColumns = [];
$scope.numColumns.length = 3;

新しいフィルター:

.filter("myFilter", function(){
    return function(input, columns){
        var filtered = [];
        for(var x = 0; x < input.length; x+= columns){
             filtered.push(input[x]);   
        }
        return filtered;
    }
});

これにより、動的にすることができます。列を変更するには、numColumns.lengthを変更するだけです。jsフィドルでは、ドロップダウンに配線したことがわかります。

jsFiddle: http: //jsfiddle.net/j4MPK/


HTMLマークアップは次のようになります。

<div data-ng-repeat="row in rows">
    <div data-ng-repeat="col in row.col">{{col}}</div>
</div>

そして、次のようにコントローラーで変数を作成できます。

$scope.rows = [
    {col: [ 1,2,3,4 ]},
    {col: [ 5,6,7 ]},
    {col: [ 9,10,11,12 ]}
]; 

このようにして、必要な数の列を作成できます。

jsfiddle http://jsfiddle.net/rtCP3/39/


編集私はフィドルを変更して、オブジェクトのフラット配列を持つことをサポートするようになりました。

jsfiddle: http: //jsfiddle.net/rtCP3/41/

HTMLは次のようになります。

<div class="row" data-ng-repeat="row in rows">
    <div class="col" data-ng-repeat="col in cols">
        {{objects[$parent.$index * numColumns + $index].entry}}
    </div>
</div>  

そして、コントローラーで私は持っています:

$scope.objects = [
    {entry: 'a'},
    {entry: 'b'},
    {entry: 'c'},
    {entry: 'd'},
    {entry: 'e'},
    {entry: 'f'},
    {entry: 'g'},
    {entry: 'h'}    
];

$scope.numColumns = 3;
$scope.rows = [];
$scope.rows.length = Math.ceil($scope.objects.length / $scope.numColumns);
$scope.cols = [];
$scope.cols.length = $scope.numColumns;

$ scope.numColumns変数は、各行に必要な列数を指定するために使用されます。


動的な配列サイズの変更を処理するには、配列の長さに注意してください(配列全体ではなく、冗長になります)。

$scope.numColumns = 3;  
$scope.rows = [];    
$scope.cols = [];    
$scope.$watch("objects.length", function(){
    $scope.rows.length = Math.ceil($scope.objects.length / $scope.numColumns);
    $scope.cols.length = $scope.numColumns;        
});

jsfiddle: http: //jsfiddle.net/rtCP3/45/

于 2013-01-02T14:00:00.787 に答える
15

このようなシンプルなものを使ってみませんか? http://jsfiddle.net/everdimension/ECCL7/3/

<div ng-controller="MyCtrl as ctr">
    <div class="row" ng-repeat="project in ctr.projects" ng-if="$index % 3 == 0">
         <h4 class="col-sm-4" ng-repeat="project in ctr.projects.slice($index, $index+3)">
            {{project}}
        </h4>
    </div>
</div>
于 2014-05-25T17:19:56.737 に答える
3

いくつかの理由から、ディレクティブをお勧めします。

  • HTMLで再利用およびパラメータ化できます(つまり、「3つおき」をディレクティブ属性にすることができます)
  • コントローラコード/$scopeプロパティを必要としないため、「things」配列のサイズが変更された場合にコントローラ$scopeプロパティを再計算する必要はありません。

推奨される要素ディレクティブは次のとおりです。

<row-generator row-data=objects col-count=3></row-generator>

実装では、サーバー側の例と同様のコードを使用しました。

myApp.directive('rowGenerator', function() {
    var rowTemplate = '<div class="row">',
        colTemplate = '<div class="span4">';
    return {
        restrict: 'E',
        // use '=' for colCount instead of '@' so that we don't
        // have to use attr.$observe() in the link function
        scope: { rowData: '=', colCount: '='},
        link: function(scope, element) {
            // To save CPU time, we'll just watch the overall
            // length of the rowData array for changes.  You
            // may need to watch more.
            scope.$watch('rowData.length', function(value) {
                var html = rowTemplate;
                for(var i=0; i < scope.rowData.length; i++) {
                    html += colTemplate + scope.rowData[i].key + '</div>';
                    if (i % scope.colCount == scope.colCount - 1) {
                        html += '</div>' + rowTemplate;
                    }
                }
                html += '</div>';
                // don't use replaceWith() as the $watch 
                // above will not work -- use html() instead
                element.html(html);
            })
        }
    }
});

データ:

$scope.things = [
    {key: 'one'},
    {key: 'two'},
    {key: 3},
    {key: 4},
    {key: 'five'},
    {key: 'six'},
    {key: 77},
    {key: 8}    
];

フィドル

効率的にするために、示されているディレクティブは、rowData(つまり、things)配列の長さの変更のみを検索します。配列要素の1つの値が変更された場合にディレクティブでビューを更新する場合は、より高価な$watchが必要になります。

scope.$watch('rowData', function(value){ ... }, true)

最後に、trueは「浅い」ダーティチェックを実行します(「参照ではなく、オブジェクトが等しいかどうかを比較します) 。ドキュメントを参照してください。

ディレクティブについて私が気に入らないことが1つあります。それは、rowDataエントリに次の名前のプロパティがあることを知っている必要がありますkey

html += colTemplate + scope.rowData[i].key + '</div>';
于 2013-01-03T03:43:47.807 に答える