[英]How to reorder grouped items with ion-reorder
I'm trying to use ion-reorder to reorder some items in a page.我正在尝试使用ion-reorder对页面中的某些项目进行重新排序。 These item are organized in groups, so a group has several items.
这些项目按组组织,因此一个组有多个项目。 I want to organize these items inside the group, but more importantly I want to be able to change the item from a group to another.
我想在组内组织这些项目,但更重要的是我希望能够将项目从一个组更改为另一个组。
I'm facing 2 problems currently:我目前面临两个问题:
html 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>
typescript typescript
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);
}
I tried to move the <ion-reorder-group>
to several positions, but this is the only one I managed to move the correct items.我试图将
<ion-reorder-group>
移动到多个位置,但这是我唯一成功移动正确项目的位置。 If I move up, above <ion-list>
, the whole list becomes draggable and I can't move the item.如果我向上移动,在
<ion-list>
上方,整个列表变得可拖动,我无法移动该项目。
I understand that this is happening because the <ion-reorder-group>
is created 2 times, but I can't think in a way to create only one time and maintain the same aspect, which is exactly like the documentation page that I linked.我知道这是因为
<ion-reorder-group>
创建了 2 次,但我想不出只创建一次并保持相同方面的方式,这与我链接的文档页面完全一样. The difference is that in there they load the items individually, and the groups are just another item that can be drag around.不同之处在于,他们在那里单独加载项目,而组只是另一个可以拖动的项目。
The other problem I believe is related to how complete()
works.我认为另一个问题与
complete()
的工作方式有关。 Although it expects any[]
as a parameter, I don't think it was made to support a complex structure, just a simple array.虽然它期望
any[]
作为参数,但我不认为它是为了支持复杂的结构而设计的,只是一个简单的数组。
How can I solve these two problems?我该如何解决这两个问题?
I'm using Ionic 5 with Angular 10我将 Ionic 5 与 Angular 10 一起使用
For the reording issue, you have two things对于重新排序问题,您有两件事
complete
function, it should be the rendered items ( groupArray[index].items
), not the root object itself ( groupArray
).complete
的 function,它应该是呈现的项目( groupArray[index].items
),而不是根 object 本身( groupArray
)。ion-list-header
should be above the ion-reorder-group
, so Ionic won't treat it as a child of the ion-reorder-group
and mess up the reording logic for the array. ion-list-header
应该在ion-reorder-group
之上,因此 Ionic 不会将其视为ion-reorder-group
的子级,并且会弄乱数组的重新排序逻辑。 Even though the example in the attached link for the ion-reorder is using one big ion-reorder-group
and the ion-list-header
to add some list headers, but this won't work if you need to update the array using the complete
.即使ion-reorder 附加链接中的示例使用一个大
ion-reorder-group
和ion-list-header
添加一些列表标题,但如果您需要使用更新数组,这将不起作用complete
。
You can do something like this to make it work:你可以做这样的事情来使它工作:
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: 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>
At the same time, you can't move an ion-item from one group to another.同时,您不能将离子项目从一组移动到另一组。 What I can think of for handling this issue is to have one big
ion-reorder-group
with the ion-list-header
, and do the reording manually.我能想到的处理这个问题是有一个大
ion-reorder-group
和ion-list-header
,并手动进行重新排序。 Accessing the target
property from the event that was sent to the doReorder
function, then you can access the children, filter only the ion-item
then reflect the sorting to the array (even though it is a very ugly workaround).从发送到
doReorder
function 的事件中访问target
属性,然后您可以访问子项,仅过滤ion-item
然后将排序反映到数组中(即使这是一个非常丑陋的解决方法)。
I actually thought of a better solution.我实际上想到了一个更好的解决方案。 You can create a new array that contains all the items flattened.
您可以创建一个包含所有展平项目的新数组。 Then when you want to submit you changes, there will be a function that will create the new order for you.
然后,当您要提交更改时,将会有一个 function 将为您创建新订单。 You can check the following Stackblitz: https://stackblitz.com/edit/ionic-5-angular-10-start-template-zasssd?file=src/app/tab1/tab1.page.ts
您可以检查以下 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);
}
I personally used this approach.我个人使用了这种方法。
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);
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.