AngularJS按表头对行进行排序
Posted
技术标签:
【中文标题】AngularJS按表头对行进行排序【英文标题】:AngularJS sorting rows by table header 【发布时间】:2013-10-08 00:16:52 【问题描述】:我有四个表头:
$scope.headers = ["Header1", "Header2", "Header3", "Header4"];
我希望能够通过单击标题对表格进行排序。
如果我的桌子是这样的
H1 | H2 | H3 | H4
A H D etc....
B G C
C F B
D E A
然后我点击
H2
我的桌子现在看起来像这样:
H1 | H2 | H3 | H4
D E A etc....
C F B
B G C
A H D
也就是说,每列的内容永远不会改变,但是通过单击我想要对列进行排序的标题,行将自行重新排序。
我的表的内容是通过使用Mojolicious 完成的数据库调用创建的,并返回到浏览器
$scope.results = angular.fromJson(data); // This works for me so far
我拼凑的其余代码如下所示:
<table class= "table table-striped table-hover">
<th ng-repeat= "header in headers">
<a> headers[$index] </a>
</th>
<tr ng-repeat "result in results">
<td> results.h1 </td>
<td> results.h2 </td>
<td> results.h3 </td>
<td> results.h4 </td>
</tr>
</table>
我如何从这一点开始对列进行排序,只需单击表格顶部的标题?
【问题讨论】:
你为什么不做<a> header </a>
而不是<a> headers[$index] </a>
?
两者都有效。 Idk,似乎更明确的是哪个标头被丢弃了。
我认为我写它的方式更像是“最佳实践”
我同意你的看法。但无论 OP 决定什么,它在 heaers 和 rows 中都应该是一致的,而目前并非如此。
【参考方案1】:
试试这个:
首先改变你的控制器
yourModuleName.controller("yourControllerName", function ($scope)
var list = [
H1:'A', H2:'B', H3:'C', H4:'d' ,
H1:'E', H2:'B', H3:'F', H4:'G' ,
H1:'C', H2:'H', H3:'L', H4:'M' ,
H1:'I', H2:'B', H3:'E', H4:'A'
];
$scope.list = list;
$scope.headers = ["Header1", "Header2", "Header3", "Header4"];
$scope.sortColumn = 'Header1';
$scope.reverseSort = false;
$scope.sortData = function (columnIndex)
$scope.reverseSort = ($scope.sortColumn == $scope.headers[columnIndex]) ? !$scope.reverseSort : false;
$scope.sortColumn = $scope.headers[columnIndex];
);
然后像这样在html端更改代码
<th ng-repeat= "header in headers">
<a ng-click="sortData($index)"> headers[$index] </a>
</th>
<tr ng-repeat "result in results | orderBy : sortColumn : reverseSort">
<td> results.h1 </td>
<td> results.h2 </td>
<td> results.h3 </td>
<td> results.h4 </td>
</tr>
【讨论】:
【参考方案2】:我找到了解决这个问题的最简单方法。如果有效率,你可以使用
HTML 代码:import angular.min.js
和 angular.route.js
库
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>like/dislike</title>
</head>
<body ng-app="myapp" ng-controller="likedislikecntrl" bgcolor="#9acd32">
<script src="./modules/angular.min.js"></script>
<script src="./modules/angular-route.js"></script>
<script src="./likedislikecntrl.js"></script>
</select></h1></p>
<table border="5" align="center">
<thead>
<th>professorname <select ng-model="sort1" style="background-color:
chartreuse">
<option value="+name" >asc</option>
<option value="-name" >desc</option>
</select></th>
<th >Subject <select ng-model="sort1">
<option value="+subject" >asc</option>
<option value="-subject" >desc</option></select></th>
<th >Gender <select ng-model="sort1">
<option value="+gender">asc</option>
<option value="-gender">desc</option></select></th>
<th >Likes <select ng-model="sort1">
<option value="+likes" >asc</option>
<option value="-likes" >desc</option></select></th>
<th >Dislikes <select ng-model="sort1">
<option value="+dislikes" >asc</option>
<option value="-dislikes">desc</option></select></th>
<th rowspan="2">Like/Dislike</th>
</thead>
<tbody>
<tr ng-repeat="sir in sirs | orderBy:sort1|orderBy:sort|limitTo:row" >
<td >sir.name</td>
<td>sir.subject|uppercase</td>
<td>sir.gender|lowercase</td>
<td>sir.likes</td>
<td>sir.dislikes</td>
<td><button ng-click="ldfi1(sir)" style="background-color:chartreuse"
>Like</button></td>
<td><button ng-click="ldfd1(sir)" style="background-
color:chartreuse">Dislike</button></td>
</tr>
</tbody>
</table>
</body>
</html>
javascript Code::likedislikecntrl.js
var app=angular.module("myapp",["ngRoute"]);
app.controller("likedislikecntrl",function ($scope)
var sirs=[
name:"Srinivas",subject:"dmdw",gender:"male",likes:0,dislikes:0,
name:"Sharif",subject:"dms",gender:"male",likes:0,dislikes:0,
name:"Chaitanya",subject:"daa",gender:"male",likes:0,dislikes:0,
name:"Pranav",subject:"wt",gender:"male",likes:0,dislikes:0,
name:"Anil Chowdary",subject:"ds",gender:"male",likes:0,dislikes:0,
name:"Rajesh",subject:"mp",gender:"male",likes:0,dislikes:0,
name:"Deepak",subject:"dld",gender:"male",likes:0,dislikes:0,
name:"JP",subject:"mp",gender:"male",likes:0,dislikes:0,
name:"NagaDeepthi",subject:"oose",gender:"female",likes:0,dislikes:0,
name:"Swathi",subject:"ca",gender:"female",likes:0,dislikes:0,
name:"Madavilatha",subject:"cn",gender:"female",likes:0,dislikes:0
]
$scope.sirs=sirs;
$scope.ldfi1=function (sir)
sir.likes++
$scope.ldfd1=function (sir)
sir.dislikes++
$scope.row=8;
)
【讨论】:
【参考方案3】:您可以使用不带箭头的代码.....即通过单击标题,它会自动显示元素的升序和降序
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="scripts/angular.min.js"></script>
<script src="Scripts/Script.js"></script>
<style>
table
border-collapse: collapse;
font-family: Arial;
td
border: 1px solid black;
padding: 5px;
th
border: 1px solid black;
padding: 5px;
text-align: left;
</style>
</head>
<body ng-app="myModule">
<div ng-controller="myController">
<br /><br />
<table>
<thead>
<tr>
<th>
<a href="#" ng-click="orderByField='name'; reverseSort = !reverseSort">
Name
</a>
</th>
<th>
<a href="#" ng-click="orderByField='dateOfBirth'; reverseSort = !reverseSort">
Date Of Birth
</a>
</th>
<th>
<a href="#" ng-click="orderByField='gender'; reverseSort = !reverseSort">
Gender
</a>
</th>
<th>
<a href="#" ng-click="orderByField='salary'; reverseSort = !reverseSort">
Salary
</a>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="employee in employees | orderBy:orderByField:reverseSort">
<td>
employee.name
</td>
<td>
employee.dateOfBirth | date:"dd/MM/yyyy"
</td>
<td>
employee.gender
</td>
<td>
employee.salary
</td>
</tr>
</tbody>
</table>
</div>
<script>
var app = angular
.module("myModule", [])
.controller("myController", function ($scope)
var employees = [
name: "Ben", dateOfBirth: new Date("November 23, 1980"),
gender: "Male", salary: 55000
,
name: "Sara", dateOfBirth: new Date("May 05, 1970"),
gender: "Female", salary: 68000
,
name: "Mark", dateOfBirth: new Date("August 15, 1974"),
gender: "Male", salary: 57000
,
name: "Pam", dateOfBirth: new Date("October 27, 1979"),
gender: "Female", salary: 53000
,
name: "Todd", dateOfBirth: new Date("December 30, 1983"),
gender: "Male", salary: 60000
];
$scope.employees = employees;
$scope.orderByField = 'name';
$scope.reverseSort = false;
);
</script>
</body>
</html>
【讨论】:
【参考方案4】:我只是被角弄湿了,但我找到了this great tutorial. 这是一个有效的plunk,我将归功于 Scott Allen 和上述教程。单击搜索以显示可排序表。
对于每个列标题,您需要使其可点击 - ng-click 链接将起作用。这将设置要排序的列的 sortName。
<th>
<a href="#" ng-click="sortName='name'; sortReverse = !sortReverse">
<span ng-show="sortName == 'name' && sortReverse" class="glyphicon glyphicon-triangle-bottom"></span>
<span ng-show="sortName == 'name' && !sortReverse" class="glyphicon glyphicon-triangle-top"></span>
Name
</a>
</th>
然后,在表格正文中,您可以在 orderBy 过滤器 orderBy:sortName:sortReverse 中通过管道输入该 sortName
<tr ng-repeat="repo in repos | orderBy:sortName:sortReverse | filter:searchRepos">
<td>repo.name</td>
<td class="tag tag-primary">repo.stargazers_count | number</td>
<td>repo.language</td>
</tr>
【讨论】:
【参考方案5】:这是一个按标题排序的示例。此表是动态的,会随 JSON 大小而变化。
我能够根据其他人的示例和文档构建动态表。 http://jsfiddle.net/lastlink/v7pszemn/1/
<tr>
<th class="header" ng-repeat="(header, value) in items[0]" ng-click="changeSorting(header)">
header
<i ng-class="selectedCls2(header)"></i>
</tr>
<tbody>
<tr ng-repeat="row in pagedItems[currentPage] | orderBy:sort.sortingOrder:sort.reverse">
<td ng-repeat="cell in row">
cell
</td>
</tr>
虽然列是无序的,但在我的 .NET 项目中它们是有序的。
【讨论】:
【参考方案6】:在 AngularJS 中执行此操作的另一种方法是使用网格。
网格的优点是默认包含您要查找的行排序行为。
功能被很好地封装。不需要添加 ng-click 属性,也不需要使用作用域变量来维护状态:
<body ng-controller="MyCtrl">
<div class="gridStyle" ng-grid="gridOptions"></div>
</body>
您只需将网格选项添加到您的控制器:
$scope.gridOptions =
data: 'myData.employees',
columnDefs: [
field: 'firstName',
displayName: 'First Name'
,
field: 'lastName',
displayName: 'Last Name'
,
field: 'age',
displayName: 'Age'
]
;
完整的工作 sn-p 附加:
var app = angular.module('myApp', ['ngGrid', 'ngAnimate']);
app.controller('MyCtrl', function($scope)
$scope.myData =
employees: [
firstName: 'John',
lastName: 'Doe',
age: 30
,
firstName: 'Frank',
lastName: 'Burns',
age: 54
,
firstName: 'Sue',
lastName: 'Banter',
age: 21
]
;
$scope.gridOptions =
data: 'myData.employees',
columnDefs: [
field: 'firstName',
displayName: 'First Name'
,
field: 'lastName',
displayName: 'Last Name'
,
field: 'age',
displayName: 'Age'
]
;
);
/*style.css*/
.gridStyle
border: 1px solid rgb(212,212,212);
width: 400px;
height: 200px
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular-animate.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body ng-controller="MyCtrl">
<div class="gridStyle" ng-grid="gridOptions"></div>
</body>
</html>
【讨论】:
不错的选择。太糟糕了,它依赖于 jQuery。 最新的ui-grid不再依赖jQuery。它仍然不稳定但值得一试:ui-grid.info【参考方案7】:这是一个可以帮助您使用 AngularJS 做到这一点的小提琴http://jsfiddle.net/patxy/D2FsZ/
<th ng:repeat="(i,th) in head" ng:class="selectedCls(i)" ng:click="changeSorting(i)">
th
</th>
那么你的数据是这样的:
<tr ng:repeat="row in body.$orderBy(sort.column, sort.descending)">
<td>row.a</td>
<td>row.b</td>
<td>row.c</td>
</tr>
在你的 AngularJS 控制器中使用这样的功能:
scope.sort =
column: 'b',
descending: false
;
scope.selectedCls = function(column)
return column == scope.sort.column && 'sort-' + scope.sort.descending;
;
scope.changeSorting = function(column)
var sort = scope.sort;
if (sort.column == column)
sort.descending = !sort.descending;
else
sort.column = column;
sort.descending = false;
;
【讨论】:
这个小提琴使用的是非常旧版本的 Angular,所以在查看代码时请注意这一点。 答案是 2013 年的,小提琴是 2010 年的,小提琴使用的是 1.0 之前的版本。他们现在是 1.2/1.3 这是我的小提琴...小提琴是 2013 年的。2010 年我对编程一无所知...【参考方案8】:使用第三方 JavaScript 库。它会给你带来更多。一个很好的例子是数据表(如果你也在使用 jQuery):https://datatables.net
或者只是在单击标题时在 $scope.results 中订购您的绑定数组。
【讨论】:
这应该仍然允许我使用 Json 对象从数据库中检索数据吗?这看起来不错,但我有点需要它来处理我迄今为止所拥有的东西。它与 Angular JS 配合得很好? 我不明白为什么不这样做,在网上搜索有人已经建立了一个你可以使用的指令(虽然看看代码,看看它是否写得好):groups.google.com/forum/m/#!topic/angular/vM2DEMK_NMA 好吧,我将备份我目前拥有的并尝试实现它,它看起来很酷。谢谢:D 您也可以在 $scope.results 中订购您的阵列,但为此制作良好的用户体验是浪费时间。另外,我保证你以后会需要更高级的东西,这些东西已经存在于数据表中了 :) 祝你好运! 我怎样才能像你说的那样订购我的阵列?我稍后会回去调查,但不,我只需要明天可以对列进行排序【参考方案9】:我认为我创建的这个working CodePen example 将准确地告诉你如何做你想做的事。
模板:
<section ng-app="app" ng-controller="MainCtrl">
<span class="label">Ordered By: orderByField, Reverse Sort: reverseSort</span><br><br>
<table class="table table-bordered">
<thead>
<tr>
<th>
<a href="#" ng-click="orderByField='firstName'; reverseSort = !reverseSort">
First Name <span ng-show="orderByField == 'firstName'"><span ng-show="!reverseSort">^</span><span ng-show="reverseSort">v</span></span>
</a>
</th>
<th>
<a href="#" ng-click="orderByField='lastName'; reverseSort = !reverseSort">
Last Name <span ng-show="orderByField == 'lastName'"><span ng-show="!reverseSort">^</span><span ng-show="reverseSort">v</span></span>
</a>
</th>
<th>
<a href="#" ng-click="orderByField='age'; reverseSort = !reverseSort">
Age <span ng-show="orderByField == 'age'"><span ng-show="!reverseSort">^</span><span ng-show="reverseSort">v</span></span>
</a>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="emp in data.employees|orderBy:orderByField:reverseSort">
<td>emp.firstName</td>
<td>emp.lastName</td>
<td>emp.age</td>
</tr>
</tbody>
</table>
</section>
JavaScript 代码:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope)
$scope.orderByField = 'firstName';
$scope.reverseSort = false;
$scope.data =
employees: [
firstName: 'John',
lastName: 'Doe',
age: 30
,
firstName: 'Frank',
lastName: 'Burns',
age: 54
,
firstName: 'Sue',
lastName: 'Banter',
age: 21
]
;
);
【讨论】:
这是我最接近工作的地方。但是,我有一些隐藏的标题,它们只有通过打开一个模式并选择一个复选框才能隐藏(这个想法是你不应该查看与你需要的内容无关的列)排序非常适合4 个必需的列,但是当我打开模式以选择要显示的其他标题/列时,每当我下次尝试进行搜索时,页面都会重新加载..? @Zack - this example 你在说什么吗? @Zack - 如果您觉得我的回答和评论为您的原始问题提供了可行的解决方案,请接受它,以便其他寻找解决方案的人可以轻松找到它。谢谢。 谢谢,不,这不是您的示例,而是我的代码中的一些其他内容,我觉得不需要编写来表达我的意思。这些问题已得到解决,您的回答已被接受:) 非常感谢,我一直在寻找适用于 Angular 1.2 的解决方案以上是关于AngularJS按表头对行进行排序的主要内容,如果未能解决你的问题,请参考以下文章
SQL 最佳实践 - 可以依靠自动增量字段按时间顺序对行进行排序吗?