使用可观察对象如何映射嵌套的动态对象键?使用 angular-日历事件

Working with observables how to map nested dynamic object keys? Using angular-calendar events

我想也许使用像 map 这样的东西比我目前正在做的更好。希望我能收到一些关于如何让它工作的建议。目前的结果是没有事件被映射,因为我映射不正确所以路径是错误的。

我的主要问题是 bks.fname 未定义,因为路径错误。正确的路径是 [“05182020”].Peeter.[-MCcGOMe0FT1IqvlCJkd].fname

但我如何在模型中定义它?

** 返回 Json 每个键都是动态的:**


05182020:
   Peteer:
     -MCcGOMe0FT1IqvlCJkd:   //The start of the book model
        date: "05/18/2020"
        name: "Peteer"
        service: "b"
        shop: "Howards"
        time: "10:00 AM"

模特:

export interface Books {
    date?: string;
    fname?: string;
    lname?: string
    name?: string;
    service?: string;
    shop?: string
    time?: string;
}


export interface IDictionary<T> {
    [index:string]: Books;
}

export interface Bookings {
  [index:string]: Books;
}

export interface CalendarEvent<MetaType = any> {
    id?: string | number;
    start: Date;
    end?: Date;
    title: string;
    color?: EventColor;
    actions?: EventAction[];
    allDay?: boolean;
    cssClass?: string;
    resizable?: {
        beforeStart?: boolean;
        afterEnd?: boolean;
    };
    draggable?: boolean;
    meta?: MetaType;
}

TS 注意:bks.fname 和其他未定义,因为当前 map((results) => 接受根对象而不仅仅是 Books 模型。

Calaendar.component.ts

events$: Observable<CalendarEvent<IDictionary<Books>>[]>;

   this.events$ = this.fs.getFullList2(this.shopName)

      .pipe(
        catchError(err => {
          console.log(err)
          return throwError(err);
        }),
        first(),
        tap(results =>
          console.log("bookings:", results[0])
        ),
        map((results) => {
          return results.map((bks: Books) => {
           return {
              title: bks.fname + " " + bks.lname + " ---Time: " + bks.time + " , Service: " + bks.service,
              start: new Date(bks.date),
              color: colors.red,
              allDay: true,
              meta: bks,//.time,
            };
          }
          );
        }
         ));


fireserveice.ts

  getFullList2(shop: string): Observable<any> {

    return this.db.list(shop,ref=>ref.limitToFirst(1)).valueChanges()
  }

由于您的问题不是很清楚,因此很难提供帮助。您期望您的输出是什么样的?您的输入是(以 round-about 方式)一系列书籍。这个流输出什么? CalendarEvents 或 CalendarEvents 的数组?

我最好的猜测是使用 mergeMap 在你找到它们时一个接一个地输出 CalendarEvent。如果您希望输出是 CalendarEvent 的数组,您需要切换回 map() 而不是 mergeMap()

我还没有测试过这个,但这是我最好的猜测,

mergeMap(results =>
  results.flatMap(idObj =>
    Object.values(idObj).flatMap(nameObj =>
      Object.values(nameObj).map((book: Books) => ({
        title: book.fname + " " + book.lname + " ---Time: " + book.time,
        service: book.service,
        start: new Date(book.date),
        color: colors.red,
        allDay: true,
        meta: book
      }))
    )
  )
)

我希望您能对它进行一些调整,使其适合您的需要。


一些与您的问题无关但可能感兴趣的事情。

1- 这个接口:

export interface IDictionary<T> {
    [index:string]: Books;
}

确实没有意义。您根本没有使用泛型,所以我不会包含它。

2- 这个接口:

export interface Bookings {
  [index:string]: Books;
}

你的问题根本没有用到。

3- 你的图书界面描述了一本书。这不是真正的问题,但是对于 return Books 但只有 return 一本书的功能会很奇怪。例如

getBookById(id: number): Books {
  // some code here
}

return 是代表一本书的单个对象,但方法签名暗示它 return 是多本书。