在 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>

希望这对遇到同样问题的人有所帮助