我在这里找到了一个例子https://jdanyow.github.io/aurelia-converters-sample/(搜索SortValueConverter) - 只需要以某种方式扩展toView函数:
export class SortValueConverter {
toView(array, propertyName, direction) {
var factor = direction === 'ascending' ? 1 : -1;
return array
.slice(0)
.sort((a, b) => {
return (a[propertyName] - b[propertyName]) * factor
});
}
}
这样它不仅可以对每一行进行排序,还可以对它进行排序:
在我的js代码中,我已经将数组弄平了,所以我可以在表格中显示它。 isGroup:true / false标记新组开始时。
如何重写排序值转换器(理想情况下)对行组和行组子进行排序,例如。按字母顺序排列的asc / desc。我想它不必使用值转换器完成,但理论上可以直接在js代码中的数组上完成,但我认为最好的解决方案是扩展排序值转换器以支持此行分组也是。
将此示例保持为"简单"尽可能让我们将行对象减少到最低限度:
{
name: 'group or robot name'
isGroup: true/false
}
所以,例如。
[
{
name: 'robots',
isGroup: true
},
{
name: 'R2-D2',
isGroup: false
},
{
name: 'terminator',
isGroup: false
},
{
name: 'wall-e',
isGroup: false
},
{
name: 'robocop',
isGroup: false
},
{
name: 'C-3PO',
isGroup: false
},
{
name: 'animals',
isGroup: true
},
{
name: 'dog',
isGroup: false
},
{
name: 'shark',
isGroup: false
},
{
name: 'cat',
isGroup: false
},
{
name: 'monkey',
isGroup: false
}
]
有什么想法吗?
答案 0 :(得分:2)
我建议稍微更改您的数据结构。您目前拥有的数据结构有点模棱两可,因为列表的排序决定了项目所在的组。我会将结构更改为:
[
{
name: 'R2-D2',
group: 'robots'
},
//...
然后,我们可以使用如下所示的值转换器对此数组进行分组和排序:
export class GroupedSortValueConverter {
toView(value) {
let sortedArray = value.splice(0).sort((a, b) => {
const left = a.name,
right = b.name;
return caseInsensitiveStringComparer(left, right);
});
const groups = new Map();
for (let item of sortedArray) {
let group = groups.get(item.group);
if (group === undefined) {
groups.set(item.group, [item]);
} else {
group.push(item);
}
}
let sortedGroups = new Map(Array.from(groups.entries()).sort((a, b) => {
const left = a[0];
const right = b[0];
return caseInsensitiveStringComparer(left, right);
}));
return sortedGroups;
}
}
function caseInsensitiveStringComparer(left, right) {
const lowerLeft = left.toLowerCase(),
lowerRight = right.toLowerCase();
if (lowerLeft < lowerRight) { //sort string ascending
return -1;
} else if (lowerLeft > lowerRight) {
return 1;
} else {
return 0;
}
}
我们可以使用这样的代码迭代这个Map。请注意,我不得不使用模板元素来包装组中继器,因为转发器没有单一的“自然包装元素”:
<template>
<require from="./grouped-sort"></require>
<table>
<template repeat.for="[group, items] of myArray | groupedSort">
<tr>
<td>
${group}
</td>
</tr>
<tr repeat.for="item of items">
<td>
${item.name}
</td>
</tr>
</template>
</table>
</template>
这里有一个可运行的要点:https://gist.run/?id=27a6e61996cb884d97fbeed0acb310bf
请注意,我使用此StackOverflow答案来帮助生成此答案:Is it possible to sort a ES6 map object?
答案 1 :(得分:1)
您可以让转换器为您执行此操作,而不是在将数据提交到值转换器之前展平数据。这样做可以更轻松地对多个条件(组和项名称)进行排序。
我假设您的数据格式与此类似:
let groups = [{
name: "robots",
items: ['R2D2', 'terminator', 'wall-e', 'robocop']
}, {
name: "animals",
items: ['dog', 'shark', 'cat', 'monkey']
}];
这是值转换器:
export class SortValueConverter {
toView(array, direction = 'ascending') {
let factor = direction === 'ascending' ? 1 : -1;
let arrayToSort = array.slice(0); // Use a copy.
// Sort the items within each group.
for (let group of arrayToSort) {
group.items = group.items.slice(0).sort((a, b) => (a > b ? 1 : -1) * factor); // Sort a copy of the items.
}
// Now sort the groups.
arrayToSort.sort((a, b) => (a.name > b.name ? 1 : -1) * factor);
// Flatten the result.
let result = [];
for (let group of arrayToSort) {
result.push({name: group.name, isGroup: true});
for (let item of group.items) {
result.push({name: item, isGroup: false});
}
}
return result;
}
}
请注意,为了简单起见,我取出了propertyName参数,但如果您想对其他类似的数据结构执行此操作,则可以轻松添加它以获得更大的灵活性。