使用 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>
我的代码重复来自 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>