如何使用 ion-reorder 对分组项目重新排序

leo*_*med 4 ionic-framework angular

我正在尝试使用ion-reorder对页面中的某些项目重新排序。这些项目按组组织,因此一个组有多个项目。我想在组内组织这些项目,但更重要的是我希望能够将项目从一个组更改为另一个组。

我目前面临两个问题:

  • 我无法更新数组,因此更改后项目订单无法正确显示。
  • 我无法将项目移到其组之外,因此我无法移动到另一个组。

html

<ion-content>   
    <ion-list *ngFor='let group of groupArray'>
        <ion-reorder-group (ionItemReorder)="doReorder($event)" disabled="false">
            <ion-list-header>{{group.name}}</ion-list-header>           
            <ion-item *ngFor='let item of group.items'>
                <ion-reorder slot="start"></ion-reorder>
                <ion-label>
                    {{item.name}}
                </ion-label>
            </ion-item>
        </ion-reorder-group>
    </ion-list>     
</ion-content>
Run Code Online (Sandbox Code Playgroud)

打字稿

interface Item {
    id: number,
    name: string
}
interface Group {
    name: string,
    items: Item[]
}
interface GroupArray extends Array<Group>{}

...

private groupArray: GroupArray = [
    {
        name: 'FirstGroup',
        items: [
            {
                id: 1,
                name: 'FirstItem'
            },{
                id: 2,
                name: 'SecondItem'
            },{
                id: 3,
                name: 'ThirdItem'
            }
        ]
    },
    {
        name: 'SecondGroup',
        items: [
            {
                id: 4,
                name: 'FourthItem'
            },{
                id: 5,
                name: 'FifthItem'
            },{
                id: 6,
                name: 'SixthItem'
            }
        ]
    }       
];

/** Reorder */
doReorder(ev: CustomEvent<ItemReorderEventDetail>) {
    this.groupArray = ev.detail.complete(this.groupArray);
}
Run Code Online (Sandbox Code Playgroud)

我尝试将其移动<ion-reorder-group>到多个位置,但这是我唯一能够移动正确项目的位置。如果我向上移动,<ion-list>则整个列表将变得可拖动,并且我无法移动该项目。

我知道发生这种情况是因为<ion-reorder-group>创建了两次,但我无法想出一种只创建一次并维护相同方面的方法,这与我链接的文档页面完全相同。不同之处在于,它们单独加载项目,而组只是另一个可以拖动的项目。

我认为另一个问题与complete()工作原理有关。虽然它需要any[]作为参数,但我不认为它是为了支持复杂的结构而设计的,只是一个简单的数组。

我该如何解决这两个问题?


我正在使用 Ionic 5 和 Angular 10

堆栈闪电战

yaz*_*han 5

对于重新排序问题,你有两件事

  • 您向函数发送了错误的项目complete,它应该是渲染的项目 ( groupArray[index].items),而不是根对象本身 ( groupArray)。
  • 应该ion-list-header位于 之上ion-reorder-group,因此 Ionic 不会将其视为 的子级ion-reorder-group并弄乱数组的重新排序逻辑。

尽管离子重新排序的附加链接中的示例使用一个大的ion-reorder-groupion-list-header添加一些列表标题,但如果您需要使用 更新数组,这将不起作用complete

你可以做这样的事情来让它工作:

doReorder(ev: CustomEvent<ItemReorderEventDetail>, groupId: number) {
  let groupToChangeIndex = this.groupArray.findIndex(
    group => group.id === groupId
  );
  this.groupArray[groupToChangeIndex].items = ev.detail.complete(
    this.groupArray[groupToChangeIndex].items
  );
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<ion-content>
  <ion-list *ngFor='let group of groupArray'>
    <ion-list-header>{{group.name}}</ion-list-header>
    <ion-reorder-group (ionItemReorder)="doReorder($event, group.id)" disabled="false">
      <ion-item *ngFor='let item of group.items'>
        <ion-reorder slot="start"></ion-reorder>
        <ion-label>
          {{item.name}}
        </ion-label>
      </ion-item>
    </ion-reorder-group>
  </ion-list>
</ion-content>
Run Code Online (Sandbox Code Playgroud)

同时,您无法将离子项从一组移动到另一组。我能想到的处理这个问题的方法是使用ion-reorder-group,ion-list-header并手动进行重新排序。target从发送到函数的事件访问属性doReorder,然后您可以访问子级,仅过滤ion-item然后将排序反映到数组(即使这是一个非常丑陋的解决方法)。


更新

我其实想到了更好的解决方案。您可以创建一个包含所有展平项目的新数组。然后,当您想要提交更改时,将会有一个函数为您创建新订单。您可以检查以下Stackblitz:https://stackblitz.com/edit/ionic-5-angular-10-start-template-zasssd ?file=src/app/tab1/tab1.page.ts

constructor() {
  this.allItemsFlattened = this.groupArray.flatMap((group, index) => [
    { isHeader: true, index: index, name: group.name },
    ...group.items
  ]);
}

/** Reorder objects in array */
doReorder(ev: CustomEvent<ItemReorderEventDetail>) {
  this.allItemsFlattened = ev.detail.complete(this.allItemsFlattened);
}

getRightOrder() {
  const rightOrder = this.allItemsFlattened.reduce((accumlator, item) => {
    if (item.isHeader) {
      const { id, name, ...rest } = this.groupArray[item.index];
      accumlator.push({ id, name, items: [] });
    } else {
      accumlator[accumlator.length - 1].items.push(item);
    }
    return accumlator;
  }, []);
  console.log(rightOrder);
}
Run Code Online (Sandbox Code Playgroud)