AngularJS按属性和自定义过滤器排序

3

我看到很多答案和文档表明,你可以将属性名称的数组传递给Angular的orderBy过滤器以按多个字段排序。然而,我的一个对象属性是以文本形式存储的数字(字段可以是“100”,“75”,“50”或“<25”)。为了将这些值作为数字进行排序,我一直在使用:

<div ng-repeat="item in items | orderBy:sortFunction">
   {{item.itemStatus}} - {{item.itemLevel}}
</div>

//Function in controller...
$scope.sortFunction = function(item) {
   return parseInt(item.itemLevel);
}

现在我想先按item.itemStatus进行排序,然后按数字的item.itemLevel进行排序。是否有一种方法可以在不改变我的数据模型的情况下实现这一点?我可以循环遍历所有项目并添加一个新属性,该属性是数字的item.itemLevel,然后使用过滤器进行过滤。
 ng-repeat="item in items | orderBy:['itemStatus','itemLevelAsNumber']

但我想知道是否有更好的方法来完成它。我已尝试过

 ng-repeat="item in items | orderBy:['itemStatus',sortFunction]

但我认为在这种情况下使用函数期望将属性名称作为字符串返回。

谢谢!


你有没有查看过 https://dev59.com/dGQn5IYBdhLWcg3wLkkd? - Nair Athul
我没有关于如何进行二次排序的答案,但我想指出自定义比较器函数需要两个参数,因为该函数需要在集合中的两个元素之间进行比较。然后,您必须返回0,如果两个项目相等,-1如果第一个值小于第二个值,1如果第一个项目大于第二个值。 https://docs.angularjs.org/api/ng/filter/orderBy - Jeff LaFay
但我认为在那种情况下使用函数需要将属性名称作为字符串返回。不,它的工作方式与您的第一个示例相同。查看文档,因此 item in items | orderBy:['itemStatus',sortFunction] 应该没问题。 通过这个 fiddle 得到证明。 - George
@George - 你说得对。我的问题在于parseInt("<25")实际上返回的是NaN,而不是25。我猜测parseInt会忽略有效数字后面的文本,但反过来则不行。 - ItJustWerks
1个回答

1
问题出在我的sortFunction上。我没有意识到parseInt只会从混合值中提取数字,如果数字是第一个的话。
 parseInt("25") === 25; //true
 parseInt("25+") === 25; //true
 parseInt("<25") === 25; //false - actually returns NaN

我更新了sortFunction为:
 return parseInt(item.itemLevel.replace('<',''));

视图中的多级orderBy现在是我认为应该的。
 ng-repeat="item in items | orderBy:['itemStatus',sortFunction]

感谢评论!

1
我建议您使用正则表达式进行替换,因为如果您将来使用它,它会更加强大。很高兴您解决了问题,并感谢您在这里发布答案,而不是只自己留着! - George

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接