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>

我如何从这一点开始对列进行排序,只需单击表格顶部的标题?

【问题讨论】:

你为什么不做&lt;a&gt; header &lt;/a&gt; 而不是&lt;a&gt; headers[$index] &lt;/a&gt; 两者都有效。 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.jsangular.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按表头对行进行排序的主要内容,如果未能解决你的问题,请参考以下文章

C#按分数对行进行排序

如何按r中其他列中的条件对行进行排序?

SQL 最佳实践 - 可以依靠自动增量字段按时间顺序对行进行排序吗?

轻松Angularjs实现表格按指定列排序

Access 2010 SQL--在交叉表查询中按聚合函数对行进行排序

Angular JS - 使用地理位置对集合进行排序