【问题标题】:How to render a list of records in a nested manner Angular async pipe如何以嵌套方式呈现记录列表Angular异步管道
【发布时间】:2021-11-13 14:21:37
【问题描述】:

如何在 Angular 中以嵌套方式呈现单个记录列表?我有一系列约会记录。我想按天对约会进行分组。如果您使用 Javascript 中的嵌套循环自己生成 HTML,这很简单,但我不知道如何在 Angular *ngFor 中从单个列表执行此操作(使用多个列表嵌套 *ngFors 很容易)。

这是问题的简化版本。一是数据模型。

export interface Appointment {
    scheduled: Date;
    client: string;
}
  appointments$: Observable<Appointment[]>;

这是我想要呈现的方式,按天分组,然后是每天下面的客户名称列表。

最后是生成该图片的 HTML。

 <ion-item-group>
    <ion-item-divider>
      <ion-label>MON 15</ion-label>
    </ion-item-divider>
  
    <ion-item>
      <ion-label>Alfred Futter</ion-label>
    </ion-item>
    <ion-item>
      <ion-label>Around the Trumpet</ion-label>
    </ion-item>
  </ion-item-group>
  
  <ion-item-group>
    <ion-item-divider>
      <ion-label>TUE 16</ion-label>
    </ion-item-divider>
    <ion-item>
      <ion-label>Antonio Taco</ion-label>
    </ion-item>
    <ion-item>
      <ion-label>Berglunds</ion-label>
    </ion-item>
    <ion-item>
      <ion-label>Blondel and Sons</ion-label>
    </ion-item>
  </ion-item-group>

所以现在的问题是我有一组约会,通常像这样在 Angular 中迭代:

<ion-item-group *ngFor="let appt of appointments$ | async">
...
<ion-item-group>

但这只是生成 ion-item-group 的外部列表。如何使用 appts.scheduled 字段进行分组,在每天下生成离子项目的内部子组?

谢谢。

编辑:根据下面@E.Maggini 的请求,我自己的解决方案。首先,我将服务本身按天分组,如下所示:

    appointments = Object.values(_.groupBy(appointments, a => a.scheduled.getDate()));

(是的,我知道只有 getDate() 是不够的,这只是为了证明概念)

那么下面的 HTML 就足以完全按照需要呈现它:

  <ion-list>
    <ion-item-group *ngFor="let apptsOneDay of appointments$ | async">
      <ion-item-divider>
        <ion-label>{{apptsOneDay[0].scheduled}}</ion-label>
      </ion-item-divider>
      <ion-item *ngFor="let appt of apptsOneDay">
        <ion-label>{{appt.name}}</ion-label>
      </ion-item>
    </ion-item-group>    
  </ion-list>  

我更愿意根据@GaurangDhorda 的建议使用 RXJS 运算符对服务返回的 Observable 进行操作,但我无法让运算符链工作。

【问题讨论】:

  • 你也可以添加示例原始数据吗?
  • 可以使用 groupBy 运算符 rxjs 按日期合并映射所有子组数据
  • 请贴出你目前尝试过的代码
  • @royappa 这里是使用 groupBy 日期可观察管道的演示 stackblitz.com/edit/… 看看这个。谢谢。
  • @GaurangDhorda 我让您的代码在我的应用程序中运行。这十分完美!请发布您的出色答案,以便我接受。非常感谢您编写完整的示例。

标签: angular ionic-framework


【解决方案1】:

Stackblitz Link 中完成工作演示

基本上,您只需使用 groupBy、mergeMap 和 toArray rxjs 运算符将您的约会可观察到管道,这样您就可以获得 groupBy 日期数据,并且您可以将这些数据用于模板并使用嵌套的 ngFor 遍历。这是您可观察到的管道代码..

appointment$: Observable<appointmentObservable[]> = of(
this.appointmentData).pipe(
   mergeMap((parentData) => parentData),
   groupBy((parentGroup) => parentGroup.scheduled.toLocaleDateString()),
   mergeMap((group) => this.reducePipe(group)),
   toArray()
);

reducePipe(group: GroupedObservable<string, appointment>) {
  return group.pipe(
    reduce(
      (acc, cur) => {
        acc.clients.push(cur);
          return acc;
        },
        { scheduled: new Date(group.key), clients: [] }
      )
     );
 }

在上面的代码中,groupBy 运算符的这一行 parentGroup.scheduled.toLocaleDateString() 正在获取计划日期类型数据,我们将其转换为 localString 并将其传递给下一个 mergeMap 管道。然后我们使用reduce操作符,再次使用scheduled: new Date(group.key)这一行将stringDate转换为dateFormat日期。

现在 HTML 是……

<ng-container *ngIf="appointment$ | async as appointments">
   <ion-item-group *ngFor="let appointment of appointments">
      <ion-item-divider>
         <ion-label>{{ appointment.scheduled | date: 'EEE dd' }}</ion-label>
      </ion-item-divider>
      <ion-item *ngFor="let userNames of appointment.clients">
         <ion-label>{{ userNames.client }}</ion-label>
      </ion-item>
   </ion-item-group>
</ng-container>

在上面的 html 中,我们使用 appointment.scheduled | date: 'EEE dd' 带有格式的角度日期管道将日期转换为您的需要,例如 MON 21。谢谢。

【讨论】:

  • 我在我的代码中应用了这些想法,它的工作方式完全符合预期。这样我可以转换从服务返回的数据,而不是修改服务本身,所以它更干净。您为 View 本身制作了一个单独的模型 AppointmentObservable 也很有启发性,这是我一直想知道的一个完全独立的问题。感谢您分享您的时间和专业知识!
  • appointmentObservable 在这里使用,因为 clients 属性现在是数组,并且在原始约会界面中,客户端界面只是单个字符串类型。也谢谢你!!
猜你喜欢
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-02
  • 2017-07-19
  • 1970-01-01
相关资源
最近更新 更多