【问题标题】:Sortable table columns with AngularJs使用 AngularJs 的可排序表列
【发布时间】:2019-10-09 00:23:23
【问题描述】:

我正在尝试对从 JSON 源填充的数据表进行排序。我的代码如下:

HTML:

<div ng-app="myApp">
    <div ng-controller="PurchasesCtrl">
        <table cellspacing="0">
            <tr class="first">
                <th class="first" ng:click="changeSorting(purchases.date)">Date</th>
                <th ng:click="changeSorting(purchases.text)">Description</th>
                <th ng:click="changeSorting(purchases.price)">Amount</th>
                <th ng:click="changeSorting(purchases.availability)">Status</th>
            </tr>
            <tr ng-repeat="purchase in purchases.data">
                <td class="first">{{purchase.date}}</td>
                <td>{{purchase.text}}</td>
                <td>{{purchase.price}}</td>
                <td>{{purchase.availability}}</td>
            </tr>
        </table>
    </div>
</div>

JS:

var myApp = angular.module("myApp",[]);

myApp.factory("Purchases", function(){
    var Purchases = {};

    Purchases.data = [
        {
            date: "10/05/2012",
            text: "1 Lorem ipsum dolor sit amet ipsum dolor",
            price: "£123.45",
            availability: "1 Available until 10th Dec 2013"
        },
        {
            date: "24/05/2012",
            text: "2 Lorem ipsum dolor sit amet ipsum dolor",
            price: "£234.56",
            availability: "2 Available until 10th Dec 2013"
        },
        {
            date: "20/05/2012",
            text: "3 Lorem ipsum dolor sit amet ipsum dolor",
            price: "£345.67",
            availability: "3 Available until 10th Dec 2013"
        }
    ];
    return Purchases;
});

function PurchasesCtrl($scope, Purchases){
    $scope.purchases = Purchases;

    $scope.changeSorting = function(column) {
        var sort = $scope.sort;

        if (sort.column == column) {
            sort.descending = !sort.descending;
        } else {
            sort.column = column;
            sort.descending = false;
        }
    };
}

小提琴:http://jsfiddle.net/7czsM/1/

如您所见,我尝试在表格标题中添加一个点击函数来调用对数据进行排序的函数,但它不起作用。

我在这里看到了一个这样的例子,它确实有效:http://jsfiddle.net/vojtajina/js64b/14/,但是当我尝试将相同类型的东西应用到我的场景时,它很快就会崩溃;例如,我尝试通过添加以下内容以编程方式在 JSON 中添加表头:

var Purchases = {};

Purchases.head = [
        {
            date: "Date",
            text: "Text column",
            price: "Price column",
            availability: "Availability column"
        }

    Purchases.data = [
        {
            date: "10/05/2012",
            text: "1 Lorem ipsum dolor sit amet ipsum dolor",
            price: "£123.45",
            availability: "1 Available until 10th Dec 2013"
        },

这只是阻止了任何工作,但我认为可以将多组数据添加到 Angular 变量中?

我完全是 Angular 的新手,所以我真的很坚持。任何指针将不胜感激,谢谢。

【问题讨论】:

  • 你忘记使用$scope.sort函数了。
  • 嗯,抱歉,我没关注?

标签: angularjs angularjs-ng-repeat


【解决方案1】:

更新 jsfiddle:http://jsfiddle.net/gweur/

sza 是对的,您确实忘记了 $scope.sort 对象,但您也缺少 ng-repeat 中的 orderBy 过滤器

|orderBy:sort.column:sort.descending

此外,您需要将列名显式传递给 changeSorting() 函数,例如

ng-click="changeSorting('text')"  

不确定是否有其他方法可以处理此问题。

最后,ng-click 是您使用的 AngularJS 版本的正确语法。

【讨论】:

    【解决方案2】:

    另一个使表格可排序的非常好的例子

    http://jsfiddle.net/vojtajina/js64b/14/

    <th ng:repeat="(i,th) in head" ng:class="selectedCls(i)" ng:click="changeSorting(i)">{{th}}</th>
    
    scope.changeSorting = function(column) {
        var sort = scope.sort;
        if (sort.column == column) {
            sort.descending = !sort.descending;
        } else {
            sort.column = column;
            sort.descending = false;
        }
    };
    

    【讨论】:

      【解决方案3】:

      这是我的解决方案。我还将整个事情包装成一个指令。唯一的依赖是 UI.Bootstrap.pagination,它在分页方面做得很好。

      这里是plunker

      这里是github source code.

      【讨论】:

      • 您的排序有点混乱。点击名称col,你会看到:“名称1,名称10,名称11,名称12”等等(当它应该是“名称1,名称2,名称3,...”时)
      • 它基于字符串。您可以创建自己的排序方法来替换它。这个想法几乎是一样的。
      【解决方案4】:

      或者您可以使用#ngTasty 作为简单的表格指令。 github:https://github.com/Zizzamia/ng-tasty 文档:http://zizzamia.com/ng-tasty/directive/table

      【讨论】:

        【解决方案5】:

        我认为你的一些 AngularJS 样板代码,特别是设置你的控制器和工厂,可能有语法错误。

        这是您的数据在表格列排序方法上工作和扩展的示例。由于 AngularJS 擅长处理 javascript 数据结构以在 HTML 中显示,因此您只需重新排列内存中的 javascript-arrays,AngularJS 就会接受这些更改。 此示例允许单击表的标题,这将触发基于该列数据类型的排序。如果它已经在该列上排序,它将对该列进行反向排序。 类型检测是通过提供的 isNumeric() 函数完成的,并且进行了两个微小的调整:

        1. 添加了检查是否将“#”符号作为标题输入并在 toggleSort 方法中作为数字排序。如果愿意,用户可以轻松地将其删除。
        2. toggleSort 尝试按字母顺序排序时,如果捕获到 TypeError,则会切换到按数字排序。

        var myApp = angular.module("myApp", []);
        
        myApp.factory("Purchases", function() {
          var Purchases = {};
        
          Purchases.data = [{
            date: "10/05/2012",
            text: "1 Lorem ipsum dolor sit amet ipsum dolor",
            price: "£123.45",
            availability: "1 Available until 10th Dec 2013"
          }, {
            date: "24/05/2012",
            text: "2 Lorem ipsum dolor sit amet ipsum dolor",
            price: "£234.56",
            availability: "2 Available until 10th Dec 2013"
          }, {
            date: "20/05/2012",
            text: "3 Lorem ipsum dolor sit amet ipsum dolor",
            price: "£345.67",
            availability: "3 Available until 10th Dec 2013"
          }];
          return Purchases;
        });
        
        myApp.controller("PurchasesCtrl", function($scope, Purchases) {
          $scope.purchases = Purchases.data;
        
          // Dynamically get the entry headers to use with displaying the nested data via header-key lookups
          // Assumes all lines contain same key-text data
          $scope.purchasesHeaderKeys = []; // Contains only the key-data, not the values
          for (var key in $scope.purchases[0]) {
            if ($scope.purchases[0].hasOwnProperty(key)) {
              $scope.purchasesHeaderKeys.push(key);
            }
          }
        
        
          /**
           * Determine if the input value is a number or not.
           * @param n The input value to be checked for numeric status.
           * @returns true if parameter is numeric, or false otherwise.
           * 
           * This method uses the following evaluations to determine if input is a numeric:
           * 
           * 		(5); // true  
           * 		('123'); // true  
           * 		('123abc'); // false  
           * 		('q345'); // false
           * 		(null); // false
           * 		(""); // false
           *		([]); // false
           * 		('   '); // false
           * 		(true); // false
           * 		(false); // false
           * 		(undefined); // false
           * 		(new String('')); // false
           * 
           * @author C.D. (modified by)
           * @original https://stackoverflow.com/a/1421988/10930451
           * 
           */
          function isNumeric(n) {
            if (!isNaN(parseFloat(n)) && !isNaN(n - 0) && n !== null && n !== "") {
              return true;
            }
            return false;
          }
        
          /**
           * Column Sort Method (generic). Sort based on target column header or reverse sort if already selected on that.
           * @param dataSource The array of JSON data to be sorted
           * @param headers The array of JSON object-keys (table column headers) to be referenced
           * @param index The target JSON object-key to sort the table columns based upon
           * 
           * @author C.D.
           */
          $scope.lastSortIndex = 0;
          $scope.changeSorting = function(dataSource, headers, index) {
            if ($scope.lastSortIndex === index) {
              dataSource.reverse();
            } else {
              var key = headers[index];
              if (key === "#" || isNumeric(dataSource[key])) { // Compare as numeric or on '#' sign
                dataSource.sort((a, b) => parseFloat(a[key]) - parseFloat(b[key]));
              } else // Compare as Strings
              {
                try { // Attempt to sort as Strings
                  dataSource.sort((a, b) => a[key].localeCompare(b[key]));
                } catch (error) {
                  if (error.name === 'TypeError') { // Catch type error, actually sort as Numeric
                    dataSource.sort((a, b) => parseFloat(a[key]) - parseFloat(b[key]));
                  }
                }
              }
              $scope.lastSortIndex = index;
              $scope.reverseSorted = false;
            }
          }
        });
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.13/angular.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
        <html ng-app="myApp">
        
        <head>
          <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
          <title>AngularJS - Hello World</title>
        
        
          <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
          <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
        
          <link rel="stylesheet" href="style.css" />
          <script src="script.js"></script>
        </head>
        
        <body ng-controller="PurchasesCtrl">
          <div class="container">
            <table class="table table-hover	table-sm">
          		<thead>
          			<tr>
          				<th ng-repeat="header in purchasesHeaderKeys">
          					<a ng-click="changeSorting(purchases, purchasesHeaderKeys, $index)">{{ header }}</a>
          				</th>
          			</tr>
          		</thead>
          
          		<tbody>
          			<!-- Data is nested, so double-repeat to extract and display -->
          			<tr ng-repeat="row in purchases" >
          				<td ng-repeat="key in purchasesHeaderKeys">
          					{{row[key]}}
          				</td>
          			</tr>
          		</tbody>
          	</table>
          </div>
        </body>
        
        </html>

        我已经整理了一个有效的Plunker example 来演示。只需单击标题,它们就会在内存中对数组进行排序,AngularJS 将在其中获取更改并刷新 DOM 的该部分。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-09-21
          • 1970-01-01
          • 2011-01-08
          • 1970-01-01
          • 1970-01-01
          • 2015-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多