angular.js conditional markup in ng-repeat

前端 未结 3 750
遇见更好的自我
遇见更好的自我 2020-12-13 07:37

I\'m using angular.js and (for the sake of argument) bootstrap. Now I need to iterate on \"things\" and display them in \'\'rows\'\' :

3条回答
  •  春和景丽
    2020-12-13 08:28

    Edit Nov 12, 2013

    It seems that not only did angular change a little in 1.2, but that there is an even better method. I've created two filters. I tried to combine them into one but got digest errors. Here are the two filters:

    .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;
        }
    });
    

    And now the html will look like this:

    {{ column.entry }}

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


    Edit Sept 20, 2013

    While working with lots of data that needed dynamic columns I've come up with a better method.

    HTML:

    {{ objects[$parent.$index * numColumns.length + $index].entry }}

    Javascript:

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

    New Filter:

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

    This allows it to be dynamic. To change the columns just change the numColumns.length. In the js fiddle you can see I've wired it up to a dropdown.

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


    Your html markup would look like this:

    {{col}}

    And then you could make a variable in your controller like so:

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

    This way, you can have any number of columns you want.

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


    Edit I've modified the fiddle to now support having a flat array of objects:

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

    The html now looks like this:

    {{objects[$parent.$index * numColumns + $index].entry}}

    And then in the controller i have:

    $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;
    

    The $scope.numColumns variable is used to specify how many columns you want in each row.


    To handle dynamic array size changes, put a watch on the length of the array (not the whole array, that would be redundent)

    $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/

提交回复
热议问题