Ng-Repeat array to rows and columns

前端 未结 5 1818
梦谈多话
梦谈多话 2021-02-04 06:45

Thanks for taking the time to read this, I was wondering how I might be able to use ng-repeat to create a grid like box of options. I would like to take an array repeat nth num

5条回答
  •  执笔经年
    2021-02-04 07:29

    Between Performance, Dynamics and Readability

    It seems putting the logic in your JavaScript is the best method. I would just bite-the-bullet and look into:

    function listToMatrix(list, n) {
        var grid = [], i = 0, x = list.length, col, row = -1;
        for (var i = 0; i < x; i++) {
            col = i % n;
            if (col === 0) {
                grid[++row] = [];
            }
            grid[row][col] = list[i];
        }
        return grid;
    }
    
    var matrix = listToMatrix(lists, 3);
    console.log('#RedPill', matrix);
    
    • @ Params: (list, n)
      • Where list is any array and n is an arbitrary number of columns desired per row
    • @ Return: A matroid
    • @ Note: This function is designed to orient a matroid based upon an arbitrary number of columns with variance in its number of rows. In other words, x = desired-columns, y = n.

    You can then create an angular filter to handle this:

    Filter:

    angular.module('lists', []).filter('matrical', function() {
        return function(list, columns) {
            return listToMatrix(list, columns);
        };
    });
    

    Controller:

    function listOfListsController($scope) {
        $scope.lists = $http.get('/lists');
    }
    

    View:

    {{list.name}}

    With this, you can see you get n number of rows -- each containing "3" columns. When you change the number of desired columns, you'll notice the number of rows changes accordingly (assuming the list-length is always the same ;)).

    Here's a fiddle.

    Note, that you get the ol' Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!. This is because Angular is recalling the matrical function upon every iteration. Allegedly, you can use the as results alias to prevent Angular from reevaluating the collection, but I had no luck. For this, it may be better to filter the grid inside of your controller and use that value for your repeater: $filter('matrical')(items) -- but please post back if you come across an elegant way of filtering it in the ng-repeat.

    I would stress, again, you're probably heading down a dark alley by trying to write the logic in your view -- but I encourage you to try it in your view if you haven't already.

    Edit

    The use of this algorithm should be combined with a Matrical Data-Structure to provide methods of push, pop, splice, and additional methods -- in tandem with appropriate logic to complement Bi-Directional Data-Binding if desired. In other words, data-binding will not work out of the box (of course) as when a new item is added to your list, a reevaluation of the entire list must take place to keep the matrix's structural integrity.

    Suggestion: Use the $filter('matrical')($scope.list) syntax in combination with $scope.$watch and recompile/calculate item-positions for the matrix.

    Cheers!

提交回复
热议问题