使用 ng-repeat 时在 Angular 中创建行

Creating rows in Angular when using ng-repeat

我的代码重复来自 API 的帖子并连续显示 9 个帖子。我的目标是创建一个网格 - 3 行,每行 3 个帖子。我尝试的解决方案不起作用。我也尝试了 'clearfix',但没有成功。 有谁知道如何使这项工作?

代码如下:

var myApp = angular.module('myApp', ['ngRoute', 'ui.bootstrap']);

    myApp.config(function ($routeProvider) {
        $routeProvider.when('/', {
            templateUrl: 'allposts.htm',
            controller: 'PostsController'
        }).when('/post', {
            templateUrl: 'post.htm',
            controller: 'PostController'
        }).when('/addpost', {
            templateUrl: 'addpost.htm',
            controller: 'AddController'
        }).otherwise({
            redirectTo: '/'
        });
    });

    myApp.controller('PostsController', function ($scope) {
    });

    myApp.controller('PostController', function ($scope) {
    });

    myApp.controller('AddController', function ($scope) {
    });


    myApp.controller('controller', function ($scope, $http) {
        $scope.title = "My app";
        $http({
            method: 'GET',
            url: "http://jsonplaceholder.typicode.com/posts"
        }).then(function (response) {
            $scope.posts = response.data;
            $scope.post = response.data[0];
            $scope.viewby = 9;
            $scope.totalItems = $scope.posts.length;
            $scope.currentPage = 1;
            $scope.itemsPerPage = $scope.viewby;
            $scope.maxSize = 5;
        });

        $scope.setPage = function (pageNo) {
            $scope.currentPage = pageNo;
        };

        $scope.setItemsPerPage = function (num) {
            $scope.itemsPerPage = num;
            $scope.currentPage = 1; //reset to first page
        };

        $scope.getRowClass = function (index) {
            if (index % 3 === 0) {
                return "row";
            }
        };
    });
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>App</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js'></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-route.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-animate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.1.3/ui-bootstrap-tpls.js"></script>
</head>

<body layout="column" ng-app="myApp" ng-cloak ng-controller="controller">
    <h1>{{title}}</h1>
    <a href="#post">Post</a> |
    <a href="#addpost">Add a post</a>
    <script type="text/ng-template" id="allposts.htm">
        View
        <select ng-model="viewby" ng-change="setItemsPerPage(viewby)">
            <option>9</option>
            <option>18</option>
            <option>36</option>
            <option>100</option>
        </select> posts
        <div layout="row">
            <div class="col-sm-4" ng-class="getRowClass($index)"
                 ng-repeat="post in posts.slice(((currentPage-1)*itemsPerPage), ((currentPage)*itemsPerPage))">

                <a href="#post">{{post.title}}</a>
                <hr>
                <p>{{post.body}}</p>
            </div>
            <div class="clearfix" ng-if="$index % 3 == 0"></div>

        </div>
        <ul uib-pagination total-items="totalItems" ng-model="currentPage" class="pagination-sm"
            items-per-page="itemsPerPage"></ul>

    </script>
    <script type="text/ng-template" id="post.htm">
            </script>
    <script type="text/ng-template" id="addpost.htm">
            </script>
    <div ng-view></div>
</body>
</html>

您可能需要向 "row" div 添加一个 ng-repeat 以根据您的变量正确计算所需的总行数。您实际上不必使用 ng-repeat 输出任何内容,只需使用数组来确定所需的元素数量。然后调整您当前的 ng-repeat 以从正确的起始位置正确地将数组切片为所需的列数。

问题是您将 Angular Material 与 Bootstrap class 混在一起。以下示例仅使用 Bootstrap.

下一个问题是,当你制作一个网格时,例如,如果你在单个 .row 元素中使用 .col-xs-4 class 的 6 个分区,那么只有当所有 6 个分区的高度都相同。否则,视图将像您的示例一样混乱。

要解决此问题,您必须创建多个 .row 元素,为此您可以编写一个指令在视图本身中执行此操作,或者在将列表传递给视图之前整理列表。

以下示例是在控制器本身中完成的(即在传递给视图之前):

// Helper function to collate a list
Array.prototype.collate = function(collateSize) {
    var collatedList = [];

    if (collateSize <= 0) {
        return [];
    }
    angular.forEach(this, function(item, index) {
        if (index % collateSize === 0) {
            collatedList[Math.floor(index / collateSize)] = [item];
        } else {
            collatedList[Math.floor(index / collateSize)].push(item);
        }
    });

    return collatedList;
};

var myApp = angular.module('myApp', ['ngRoute', 'ui.bootstrap']);

myApp.config(function($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: 'allposts.htm',
        controller: 'PostsController'
    }).when('/post', {
        templateUrl: 'post.htm',
        controller: 'PostController'
    }).when('/addpost', {
        templateUrl: 'addpost.htm',
        controller: 'AddController'
    }).otherwise({
        redirectTo: '/'
    });
});

myApp.controller('PostsController', function($scope) {});

myApp.controller('PostController', function($scope) {});

myApp.controller('AddController', function($scope) {});


myApp.controller('controller', function($scope, $http) {
    $scope.title = "My app";
    $http({
        method: 'GET',
        url: "http://jsonplaceholder.typicode.com/posts"
    }).then(function(response) {
        $scope.posts = response.data;
        $scope.viewby = 9;
        $scope.totalItems = $scope.posts.length;
        $scope.currentPage = 1;
        $scope.itemsPerPage = $scope.viewby;
        $scope.maxSize = 5;
        $scope.collatedPosts = getCollatedPosts($scope.posts);
    });

    function getCollatedPosts(posts) {
        if (!posts) {
            return [];
        }

        var paginatedPosts = posts.slice((($scope.currentPage - 1) * $scope.itemsPerPage), (($scope.currentPage) * $scope.itemsPerPage));
        return paginatedPosts.collate(3);
    }

    $scope.setPage = function(pageNo) {
        $scope.currentPage = pageNo;
    };

    $scope.setItemsPerPage = function(num) {
        $scope.itemsPerPage = num;
        $scope.currentPage = 1; //reset to first page
        $scope.collatedPosts = getCollatedPosts($scope.posts);
    };

    $scope.pageChanged = function(currentPage) {
        $scope.currentPage = currentPage;
        $scope.collatedPosts = getCollatedPosts($scope.posts);
    };
});
.row {
  /* Using red border just for understanding */
  border-bottom: 2px solid red;
  margin-bottom: 10px;
  margin-top: 10px;
}
<html>

<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js'></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-route.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-animate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.1.3/ui-bootstrap-tpls.js"></script>
</head>

<body layout="column" ng-app="myApp" ng-cloak ng-controller="controller">
    <h1>{{title}}</h1>
    <a href="#post">Post</a> |
    <a href="#addpost">Add a post</a>
    <script type="text/ng-template" id="allposts.htm">
        View
        <select ng-model="viewby" ng-change="setItemsPerPage(viewby)">
            <option>9</option>
            <option>18</option>
            <option>36</option>
            <option>100</option>
        </select>posts
        <div class="row" ng-repeat="collatedPostList in collatedPosts">
            <div class="col-xs-4" ng-repeat="post in collatedPostList">

                <a href="#post">{{post.title}}</a>
                <hr>
                <p>{{post.body}}</p>
            </div>

        </div>
        <ul uib-pagination total-items="totalItems" ng-model="currentPage" class="pagination-sm"
            items-per-page="itemsPerPage" ng-change="pageChanged(currentPage)"></ul>

    </script>
    <script type="text/ng-template" id="post.htm">
  </script>
    <script type="text/ng-template" id="addpost.htm">
  </script>
    <div ng-view></div>
</body>

</html>