Ionic v3: Group list by date/day

时光总嘲笑我的痴心妄想 提交于 2019-12-04 15:50:06

You need a pipe to transform your data into a structure you can easily use in a template: 1 array of objects, containing other arrays of objects. Your final data should look like this:

const events = [{
  date: '2017-12-26',
  events: [{
    id: 1,
    title: 'First event'
  }, {
    id: 3,
    title: 'Third event'
  }]
}, {
  date: '2017-12-30',
  events: [{
    id: 2,
    title: 'Second event'
  }]
}, {
  date: '2017-12-31',
  events: [{
    id: 4,
    title: 'Last event'
  }]
}];

Here is my attempt at a pipe that accomplishes that:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'groupBy',
})
export class GroupByPipe implements PipeTransform {
  transform(value: any, groupByKey: string) {
    const events: any[] = [];
    const groupedElements: any = {};

    value.forEach((obj: any) => {
      if (!(obj[groupByKey] in groupedElements)) {
        groupedElements[obj[groupByKey]] = [];
      }
      groupedElements[obj[groupByKey]].push(obj);
    });

    for (let prop in groupedElements) {
      if (groupedElements.hasOwnProperty(prop)) {
        events.push({
          key: prop,
          list: groupedElements[prop]
        });
      }
    }

    return events;
  }
}

I'm sure there are better, cooler ways to do this (like in one single line with some ES6 awesomeness) but this works for now.

Now for the template, like you would in Ionic 1, you basically still have 2 loops, the first one uses the pipe to transform your data and the second (inner) loop.

Here are two versions, the second shows how the pipe can be used to group with different keys and assumes the data contains a category key in each element of the original events array:

By Date

<ion-item-group *ngFor="let group of events | groupBy: 'date'">
    <ion-item-divider color="light">
        {{ group.key }}
    </ion-item-divider>
    <ion-item *ngFor="let event of group.list">{{ event.title }}</ion-item>
</ion-item-group>

By Category

<ion-item-group *ngFor="let group of events | groupBy: 'category'">
    <ion-item-divider color="light">
        {{ group.key }}
    </ion-item-divider>
    <ion-item *ngFor="let event of group.list">{{ event.title }} {{ event.date }}</ion-item>
</ion-item-group>

You can use whatever components you wish in your template, this is straight from the Ionic Documentation.

Don't forget to import the pipe in the page where you use it. If you used lazy loading, you need to add it to the imports of the page's module.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!