【问题标题】:AngularJS sorting rows by table headerAngularJS按表头对行进行排序
【发布时间】: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 中都应该是一致的,而目前并非如此。

标签: angularjs angularjs-ng-repeat html-table


【解决方案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 的解决方案
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-13
            • 2020-02-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多