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

时间:2016-09-07 11:31:08

标签: javascript angularjs twitter-bootstrap angular-ui-bootstrap

我的代码会重复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>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

问题是您正在将Angular Material与Bootstrap类混合使用。以下示例仅使用Bootstrap。

下一个问题是,如果你在一个.col-xs-4元素中使用.row类的6个分区,那么当你创建一个网格时,那些只有在所有6个分区的高度时才会自动调整是一样的否则,视图将像您的示例一样混乱。

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

以下示例在控制器本身中进行操作(即在传递给视图之前):

&#13;
&#13;
// 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);
    };
});
&#13;
.row {
  /* Using red border just for understanding */
  border-bottom: 2px solid red;
  margin-bottom: 10px;
  margin-top: 10px;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可能需要在&#34;行&#34;中添加ng-repeat。 div根据您的变量正确计算所需的总行数。您实际上不必输出带有ng-repeat的任何内容,只需使用该数组来确定所需的元素数量。然后调整当前的ng-repeat以正确地从正确的起始位置切割数组,以获得所需的列数。