【问题标题】:How to reorder grouped items with ion-reorder如何使用 ion-reorder 重新排序分组项目
【发布时间】:2021-03-19 19:53:07
【问题描述】:

我正在尝试使用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>

打字稿

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);
}

我尝试将&lt;ion-reorder-group&gt; 移动到多个位置,但这是我唯一设法移动正确项目的位置。如果我向上移动,在&lt;ion-list&gt; 上方,整个列表变得可拖动,我无法移动该项目。

我知道发生这种情况是因为 &lt;ion-reorder-group&gt; 被创建了 2 次,但我无法想办法只创建一次并保持相同的方面,这与我链接的文档页面完全相同。不同之处在于它们在那里单独加载项目,而组只是另一个可以拖动的项目。

我认为另一个问题与complete() 的工作方式有关。虽然它期望any[] 作为参数,但我不认为它是为了支持复杂的结构,只是一个简单的数组。

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


我正在使用 Ionic 5 和 Angular 10

StackBlitz

【问题讨论】:

    标签: angular ionic-framework


    【解决方案1】:

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

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

    尽管attached link for the ion-reorder 中的示例使用一个大的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
      );
    }
    

    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>
    

    同时,您不能将离子项目从一组移动到另一组。 我能想到的处理这个问题的方法是有一个大的ion-reorder-groupion-list-header,然后手动重新排序。从发送到doReorder 函数的事件中访问target 属性,然后您可以访问子项,仅过滤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);
    }
    

    【讨论】:

    • 我尝试使用您的方法,但目标属性返回 &lt;ion-reorder-group&gt; 中的所有内容,然后按重新排列之前的顺序,因此我无法从中过滤元素,因为我不能知道什么是元素,考虑到这个列表很大而且是动态的。我试图搜索事件中的每个元素,但没有一个返回对移动对象的引用。
    • 你能为此添加一个 StackBlitz 吗?
    • 当然!我试图评论重要的事情并添加我现在正在尝试做的事情。 stackblitz.com/edit/….
    • 这是一种比我尝试做的方法更好的方法。我什至想过做这样的事情,但我什至不知道该怎么做。这也是了解更多关于flatMap()reduce() 的好机会。我相信现在这两个问题都得到了回答。非常感谢您的帮助。
    • 我很高兴听到这个消息!很高兴为您提供帮助!
    【解决方案2】:

    我个人使用了这种方法。

    ngOnint(){
    this.item.items = result[1]; 
    
    if (this.item?.itemSortOrder != null) {
    // converting string to array
    let itemSortOrder= this.item.itemSortOrder.split(","); 
    
    this.newIndexArray = itemSortOrder
                               .map((i) => this.item.items.find((j) => j.id === i))
                               .filter(e => e !== undefined && e !== null); 
        }}
        
    doReorder(ev: CustomEvent<ItemReorderEventDetail>) {
        console.log('Dragged from index', ev.detail.from, 'to', ev.detail.to);
        this.newIndexArray = ev.detail.complete(this.newIndexArray);
      }
    
    saveReorder() {
        let newOrderPosition: string[] = [];
        this.newIndexArray.forEach((x) => {
          newOrderPosition.push(x.id); //adding sorted new item id's to an array
        })
    
        //array to string
        this.item.itemSortOrder = newOrderPosition.toString();
    
       //Passing the newArray order of items to the server
        this.newService.updateCatalog(this.item)
          .subscribe((result) => {
            console.log(result);
          });
      }
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    • 2012-01-08
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多