在 Nativescript Vue 中对对象数组进行排序的正确方法是什么?
What is the proper way of sorting an array of objects in Nativescript Vue?
我目前正在尝试对 Nativescript Vue 应用程序中的项目数组进行非常简单的排序,但是它会返回一些非常奇怪的结果。我有一个 playground link 重现了这个问题。
基本上,当我的页面加载时,项目是根据排序方向的数据 属性 排序的。这是正确订购的。但是,如果我随后尝试改变这个方向(上升或下降),那么它的顺序真的很奇怪。
加载时,我的项目按如下升序排列:
然后当我尝试对它们进行降序排序时,顺序变为:
当我再次尝试升序排序时,顺序变为:
这里基本上是我的 playground 条目中的代码 - 我知道其中一些是过度设计的,但这只是我测试了很多东西的结果:
<template>
<Page>
<ActionBar title="Sort Test" icon="">
</ActionBar>
<StackLayout>
<StackLayout>
<Label :text="item.title" textWrap="true"
v-for="item in orderedItems" :key="item.id" />
</StackLayout>
<Label :text="`Sort Ascending: ${sortAscending}`"
textWrap="true" />
<Label :text="`Sort Descending: ${sortDescending}`"
textWrap="true" />
<Button text="Sort Ascending" @tap="sortAsc" />
<Button text="Sort Descending" @tap="sortDesc" />
</StackLayout>
</Page>
</template>
<script>
export default {
methods: {
sortAsc() {
this.sortAscending = true;
this.sortDescending = false;
},
sortDesc() {
this.sortAscending = false;
this.sortDescending = true;
}
},
computed: {
orderedItems() {
//return (b.date > a.date) ? 1 : (b.date < a.date) ? -1 : 0;
return this.items.sort((a, b) => {
if (this.sortAscending) {
// return (a.id > b.id) ? 1 : (a.id < b.id) ? -1 : 0;
return a.id - b.id;
} else {
// return (b.id > a.id) ? 1 : (b.id < a.id) ? -1 : 0;
return b.id - a.id;
}
});
}
},
data() {
return {
sortAscending: true,
sortDescending: false,
items: [{
id: 1,
title: "Label 1"
},
{
id: 2,
title: "Label 2"
},
{
id: 4,
title: "Label 4"
},
{
id: 5,
title: "Label 5"
},
{
id: 3,
title: "Label 3"
}
]
};
}
};
</script>
<style lang="postcss" scoped></style>
现在,我 似乎符合我的确切用例,但是改变我的 orderedItems
属性 的行为似乎没有什么不同。
我做错了什么吗?我的 v-for 是在错误的地方,还是使用计算的 属性 来显示它的副作用 - 我应该在排序方向上使用手表而不是重新排序 items
数据属性?
如有任何帮助,我们将不胜感激 - 我还没有在 iOS 上尝试过,但这种行为发生在 Android。
好吧,对于任何有兴趣的人,上面的排序解决方案工作正常 - 我不太了解,但问题似乎出在 Nativescript 呈现项目时。
我的解决方案是在排序之间添加加载状态。因此,当有人单击排序升序/降序按钮时,会出现加载消息,排序发生,然后加载状态消失。下面是一个非常初级的版本:
<template>
<Page>
<Label v-if="loadingItems">Loading Items</Label>
<StackLayout v-else>
<Label v-for="item in items" :key="item.id" :text="item.title" />
<Button @tap="sort('asc')" text="Sort Ascending" />
<Button @tap="sort('desc')" text="Sort Descending" />
</StackLayout>
</template>
<script>
export default {
data() {
return {
loadingItems: false,
items: [
{
id: 1,
title: "Item 1"
},
{
id: 3,
title: "Item 3"
},
{
id: 3,
title: "Item 3"
},
{
id: 4,
title: "Item 4"
},
{
id: 5,
title: "Item 5"
}
]
},
methods: {
sort(dir) {
this.items = this.items.sort((a,b) => {
return dir == 'asc' ? a.id - b.id : b.id - a.id
});
}
}
}
</script>
希望这对遇到同样问题的人有所帮助
我目前正在尝试对 Nativescript Vue 应用程序中的项目数组进行非常简单的排序,但是它会返回一些非常奇怪的结果。我有一个 playground link 重现了这个问题。
基本上,当我的页面加载时,项目是根据排序方向的数据 属性 排序的。这是正确订购的。但是,如果我随后尝试改变这个方向(上升或下降),那么它的顺序真的很奇怪。
加载时,我的项目按如下升序排列:
然后当我尝试对它们进行降序排序时,顺序变为:
当我再次尝试升序排序时,顺序变为:
这里基本上是我的 playground 条目中的代码 - 我知道其中一些是过度设计的,但这只是我测试了很多东西的结果:
<template>
<Page>
<ActionBar title="Sort Test" icon="">
</ActionBar>
<StackLayout>
<StackLayout>
<Label :text="item.title" textWrap="true"
v-for="item in orderedItems" :key="item.id" />
</StackLayout>
<Label :text="`Sort Ascending: ${sortAscending}`"
textWrap="true" />
<Label :text="`Sort Descending: ${sortDescending}`"
textWrap="true" />
<Button text="Sort Ascending" @tap="sortAsc" />
<Button text="Sort Descending" @tap="sortDesc" />
</StackLayout>
</Page>
</template>
<script>
export default {
methods: {
sortAsc() {
this.sortAscending = true;
this.sortDescending = false;
},
sortDesc() {
this.sortAscending = false;
this.sortDescending = true;
}
},
computed: {
orderedItems() {
//return (b.date > a.date) ? 1 : (b.date < a.date) ? -1 : 0;
return this.items.sort((a, b) => {
if (this.sortAscending) {
// return (a.id > b.id) ? 1 : (a.id < b.id) ? -1 : 0;
return a.id - b.id;
} else {
// return (b.id > a.id) ? 1 : (b.id < a.id) ? -1 : 0;
return b.id - a.id;
}
});
}
},
data() {
return {
sortAscending: true,
sortDescending: false,
items: [{
id: 1,
title: "Label 1"
},
{
id: 2,
title: "Label 2"
},
{
id: 4,
title: "Label 4"
},
{
id: 5,
title: "Label 5"
},
{
id: 3,
title: "Label 3"
}
]
};
}
};
</script>
<style lang="postcss" scoped></style>
现在,我 orderedItems
属性 的行为似乎没有什么不同。
我做错了什么吗?我的 v-for 是在错误的地方,还是使用计算的 属性 来显示它的副作用 - 我应该在排序方向上使用手表而不是重新排序 items
数据属性?
如有任何帮助,我们将不胜感激 - 我还没有在 iOS 上尝试过,但这种行为发生在 Android。
好吧,对于任何有兴趣的人,上面的排序解决方案工作正常 - 我不太了解,但问题似乎出在 Nativescript 呈现项目时。
我的解决方案是在排序之间添加加载状态。因此,当有人单击排序升序/降序按钮时,会出现加载消息,排序发生,然后加载状态消失。下面是一个非常初级的版本:
<template>
<Page>
<Label v-if="loadingItems">Loading Items</Label>
<StackLayout v-else>
<Label v-for="item in items" :key="item.id" :text="item.title" />
<Button @tap="sort('asc')" text="Sort Ascending" />
<Button @tap="sort('desc')" text="Sort Descending" />
</StackLayout>
</template>
<script>
export default {
data() {
return {
loadingItems: false,
items: [
{
id: 1,
title: "Item 1"
},
{
id: 3,
title: "Item 3"
},
{
id: 3,
title: "Item 3"
},
{
id: 4,
title: "Item 4"
},
{
id: 5,
title: "Item 5"
}
]
},
methods: {
sort(dir) {
this.items = this.items.sort((a,b) => {
return dir == 'asc' ? a.id - b.id : b.id - a.id
});
}
}
}
</script>
希望这对遇到同样问题的人有所帮助