AngularJS orderby 精炼
AngularJS orderby refining
我有 table 个以头衔开头的名字(先生、夫人等)和存储为字符串的日期以及一些其他数据。
我目前正在使用
对其进行排序
<tr dir-paginate="booking in bookingResults | orderBy:sortType:sortReverse | filter:searchPassenger | itemsPerPage: 15">
我如何改进我的 orderBy 以将不包括标题(先生、夫人等)和日期的名称排序为已解析的日期而不是字符串。
这里的最佳做法是什么?
编辑:
顺便说一句,我不想更改模型中的名称 - 我希望格式保持 "Mr Foo" 和 "Mr Bar" 但是当我对它们进行排序时,我希望它们表现得好像它们只是 "Foo" 和 "Bar".
编辑编辑:
AngularJS1.5.6
以正确的格式获取正确的数据
头衔和姓名
我会使用正则表达式从名称中提取标题:
var regex = /((Dr\.|Mr\.|Ms\.|Miss|Mrs\.)\s*)/gmi
objName.replace(regex, '')
日期
我假设您得到的是日期 object 或标准日期字符串。如果是后者,只需通过 new Date(incomingDateString)
创建一个 Date object。然后你可以调用:
objDate.getTime() //returns epoch in milliseconds
排序
有些人可能不喜欢这个,但我讨厌用 NG 指令需要用于诸如排序之类的方法弄脏视图控制器。相反,我在每个行项目上使用 ng-init
添加了一些 ng-flagged 属性。然后我可以根据它进行排序。我没有为示例中的日期执行此操作,但您可以推断并应用。
ng-initw。 ng-flagged 属性
<tr ng-repeat="row in vc.listData | orderBy:vc.sortKey track by $index"
ng-init="row.$name = row.name.replace(vc.regexp, '')">
所以换句话说,你的 object 是从这个开始的:
{
name:'Mr. Fred Rogers',
date:<date-object>
}
感谢ng-init
:
{
name:'Mr. Fred Rogers',
date:<date-object>,
$name:'Fred Rogers',
$date:1466192224091
}
然后通过排序 UI,您可以将 $scope.sortKey
设置为 $name
或 $date
。
码笔
我用代码笔做了一个样本,但我用我的模板做的,模板是 coffeescript 和 jade。你大概能猜到我在做什么。
Ok, after some research, I found that the easiest solution is upgrading to AngularJS version 1.5.7 which introduces the comparator into the orderBy filter.
So I've changed my repeater to use an order by comparator
<tr dir-paginate="booking in Results | orderBy:Variable:TrueOrFalse:bookingComparator">
Variable is a string which I bound to the table headings so you can change the order by key, TrueOrFalse is a boolean which alternates between ascending and descending if you click the table heading and bookingComparator is my actual comparator.
My booking comparator looks like this
$scope.bookingComparator = function (a, b) {
var getTitle = /((Mrs|Mr|Mstr|Miss|Dr)\s*)/g;
var isDate = /(-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-)/g
if (getTitle.test(a.value)) {
var aName = a.value, bName = b.value;
return aName.replace(getTitle, '') < bName.replace(getTitle, '') ? -1 : 1
}
if (isDate.test(a.value)) {
var aDate = new Date(a.value), bDate = new Date(b.value);
return aDate.getTime() < bDate.getTime() ? -1 : 1
}
return a.index < b.index ? -1 : 1
}
The comparator is basically a function acting like the javascript .sort() method.
If the value contains a title (Mr, Mrs, etc) it is a name so I strip the titles and compare the actual names regardless of title.
If the variable matches a -Month- pattern, it's a date string and I compare the parsed date objects.
Hope this is helpful to someone, took me a while to figure out. I'm open to suggestions if you think there's a better way of doing this, and feel free to post an answer for people who want to use AngularJS =< 1.5.6
我有 table 个以头衔开头的名字(先生、夫人等)和存储为字符串的日期以及一些其他数据。
我目前正在使用
对其进行排序<tr dir-paginate="booking in bookingResults | orderBy:sortType:sortReverse | filter:searchPassenger | itemsPerPage: 15">
我如何改进我的 orderBy 以将不包括标题(先生、夫人等)和日期的名称排序为已解析的日期而不是字符串。
这里的最佳做法是什么?
编辑: 顺便说一句,我不想更改模型中的名称 - 我希望格式保持 "Mr Foo" 和 "Mr Bar" 但是当我对它们进行排序时,我希望它们表现得好像它们只是 "Foo" 和 "Bar".
编辑编辑: AngularJS1.5.6
以正确的格式获取正确的数据
头衔和姓名
我会使用正则表达式从名称中提取标题:
var regex = /((Dr\.|Mr\.|Ms\.|Miss|Mrs\.)\s*)/gmi
objName.replace(regex, '')
日期
我假设您得到的是日期 object 或标准日期字符串。如果是后者,只需通过 new Date(incomingDateString)
创建一个 Date object。然后你可以调用:
objDate.getTime() //returns epoch in milliseconds
排序
有些人可能不喜欢这个,但我讨厌用 NG 指令需要用于诸如排序之类的方法弄脏视图控制器。相反,我在每个行项目上使用 ng-init
添加了一些 ng-flagged 属性。然后我可以根据它进行排序。我没有为示例中的日期执行此操作,但您可以推断并应用。
ng-initw。 ng-flagged 属性
<tr ng-repeat="row in vc.listData | orderBy:vc.sortKey track by $index"
ng-init="row.$name = row.name.replace(vc.regexp, '')">
所以换句话说,你的 object 是从这个开始的:
{
name:'Mr. Fred Rogers',
date:<date-object>
}
感谢ng-init
:
{
name:'Mr. Fred Rogers',
date:<date-object>,
$name:'Fred Rogers',
$date:1466192224091
}
然后通过排序 UI,您可以将 $scope.sortKey
设置为 $name
或 $date
。
码笔
我用代码笔做了一个样本,但我用我的模板做的,模板是 coffeescript 和 jade。你大概能猜到我在做什么。
Ok, after some research, I found that the easiest solution is upgrading to AngularJS version 1.5.7 which introduces the comparator into the orderBy filter.
So I've changed my repeater to use an order by comparator
<tr dir-paginate="booking in Results | orderBy:Variable:TrueOrFalse:bookingComparator">
Variable is a string which I bound to the table headings so you can change the order by key, TrueOrFalse is a boolean which alternates between ascending and descending if you click the table heading and bookingComparator is my actual comparator.
My booking comparator looks like this
$scope.bookingComparator = function (a, b) {
var getTitle = /((Mrs|Mr|Mstr|Miss|Dr)\s*)/g;
var isDate = /(-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-)/g
if (getTitle.test(a.value)) {
var aName = a.value, bName = b.value;
return aName.replace(getTitle, '') < bName.replace(getTitle, '') ? -1 : 1
}
if (isDate.test(a.value)) {
var aDate = new Date(a.value), bDate = new Date(b.value);
return aDate.getTime() < bDate.getTime() ? -1 : 1
}
return a.index < b.index ? -1 : 1
}
The comparator is basically a function acting like the javascript .sort() method.
If the value contains a title (Mr, Mrs, etc) it is a name so I strip the titles and compare the actual names regardless of title.
If the variable matches a -Month- pattern, it's a date string and I compare the parsed date objects.
Hope this is helpful to someone, took me a while to figure out. I'm open to suggestions if you think there's a better way of doing this, and feel free to post an answer for people who want to use AngularJS =< 1.5.6