我正在尝试对从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/
正如您所看到的,我已经尝试在表标题中添加一个click函数来调用一个对数据进行排序的函数,但它不起作用。
我已经看到了一个这样的事情的例子,在这里: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的新手,所以我真的很喜欢这个。任何指针都会非常感激,谢谢。
答案 0 :(得分:25)
更新了jsfiddle:http://jsfiddle.net/gweur/
sza是对的,你确实忘记了$ scope.sort对象,但是你也错过了ng-repeat中的orderBy过滤器
|orderBy:sort.column:sort.descending
此外,您需要将列名显式传递给changeSorting()函数,例如
ng-click="changeSorting('text')"
不确定是否有不同的方法可以解决这个问题。
最后,ng-click是您正在使用的AngularJS版本的正确语法。
答案 1 :(得分:7)
制作表格可排序的另一个非常好的例子
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;
}
};
答案 2 :(得分:5)
答案 3 :(得分:0)
或者你可以使用#ngTasty作为简单的表指令。 github:https://github.com/Zizzamia/ng-tasty docs:http://zizzamia.com/ng-tasty/directive/table
答案 4 :(得分:0)
我认为您的AngularJS样板代码,特别是设置Controller和Factory的代码可能存在语法错误。
这是数据工作的示例,并在表列排序方法上进行了扩展。由于AngularJS擅长处理javascript数据结构以在HTML中显示,因此您可以重新排列内存中的javascript数组,而AngularJS会进行更改。 此示例允许单击表的标题,这将触发基于该列数据类型的排序。如果已在该列上对其进行了排序,则它将对该列进行反向排序。类型检测是通过提供的isNumeric()函数和一个两个小小的调整来完成的:
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的该部分。