Могу ли я связать наблюдаемые объекты. Я что-то реализовал, но не уверен, что это лучший способ сделать это? - PullRequest
0 голосов
/ 06 августа 2020

Я пытаюсь преобразовать данные ((meetingData $ | asyn c)), используя свой собственный канал, который возвращает отфильтрованный arr как наблюдаемое. Вот мой код HTML:

<div class="meeting-dtls-sub-div" ***ngFor="let meeting of meetingData$ | async | hzCalendarFilter |async"**>
</div>

HzCalendarFilter.ts ==

@Pipe({
  name: 'hzCalendarFilter',
})
export class HzCalendarFilterPipe implements PipeTransform {
  storedFilter$ = this.store$.pipe(select(getFilters));
  appliedFilterArr: string[] = [];
  constructor(private store$: Store<AppState>) {}
  transform(HzCaleDateArr: any = []) {
    return this.storedFilter$.pipe(
      map((filterArr: ICalendarFilter[]) => {
        this.appliedFilterArr = filterArr.filter((item) => item.isEnabled).map((data) => data.className);
        if (!!HzCaleDateArr) {
          return HzCaleDateArr.map((dateItem: any) => {
            return {
              ...dateItem,
              meetings: dateItem.meetings.filter((item: any) =>
                this.checkItemPresentOrNotAccordingToAppliedFilter(item.meetingType)
              ),
            };
          });
        }
      })
    );
  }
  checkItemPresentOrNotAccordingToAppliedFilter(meetingType: string) {
    const className = returnClassNameForMeeting(meetingType);
    if (!!className) {
      return this.appliedFilterArr.indexOf(className) > -1 ? true : false;
    }
  }
}

* В настоящее время мой код работает нормально, но я не уверен, что как я делаю это нормально или нет? Может кто-нибудь, пожалуйста, дайте мне знать, нормально ли использовать цепочку конвейеров asyn c ( ngFor = "let meeting of meetingData $ | asyn c | hzCalendarFilter | asyn c")?

1 Ответ

0 голосов
/ 06 августа 2020

Код в порядке, если он работает, хотя я думал, что это может помочь.

если вы используете ngrx, вы можете использовать select с самим хранилищем, как это

storedFilter$ = this.store$.pipe(select(getFilters));

to 

storedFilter$ = this.store$.select(getFilters)

вы можете использовать каналы для Наблюдаемые также, поэтому вам не нужно использовать asyn c дважды или больше.

<div 
class="meeting-dtls-sub-div" 
*ngFor="let meeting of meetingData$ | hzCalendarFilter | async">

  ...

</div>

Мы можем писать фильтры внутри вашего канала магазина, чтобы отфильтровать отключенные:

storedFilter$ = this.store$.pipe(select(getFilters));
this.appliedFilterArr = filterArr.filter((item) => item.isEnabled).map((data) => data.className)

to

enabledStoredFilter$: Observable<string[]> = this.store$.select(getFilters).pipe(
    map((arr: ICalendarFilter[]) => {
      return arr.filter((x) => x.isEnabled);
    }),
    map((arr: ICalendarFilter[]) => arr.map((x) => x.className))
  );

И полный код:

import { Pipe, PipeTransform } from '@angular/core';
import { select, Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
interface ICalendarFilter {
  isEnabled: boolean;
  className: string;
}
interface AppState {}
interface DateItem {
  meetings: string[];
}

function returnClassNameForMeeting(name: any): any {}
@Pipe({
  name: 'hzCalendarFilter'
})
export class HzCalendarFilterPipe implements PipeTransform {
  enabledStoredFilter$: Observable<string[]> = this.store$.select(getFilters).pipe(
    map((arr: ICalendarFilter[]) => {
      return arr.filter((x) => x.isEnabled);
    }),
    map((arr: ICalendarFilter[]) => arr.map((x) => x.className))
  );

  constructor(private store$: Store<AppState>) {}

  transform(hzCaleDateArr$: Observable<DateItem[]>) {
    return hzCaleDateArr$.pipe(this.applyStoreFilters);
  }

  get applyStoreFilters() {
    return switchMap((arrayOfDateItems: DateItem[]) => {
      return this.enabledStoredFilter$.pipe(
        map((filters) => {
          return this.addMeetingsToDateItemArray(arrayOfDateItems, filters);
        })
      );
    });
  }

  addMeetingsToDateItemArray(arrayOfDateItems: DateItem[], appliedFilterArr: string[]) {
    return arrayOfDateItems.map((dateItem: DateItem) => this.filterMeetingOfDateItem(dateItem, appliedFilterArr));
  }

  filterMeetingOfDateItem(dateItem: DateItem, filtersToApply) {
    const meetings = dateItem.meetings.filter((item: any) => {
      const className = returnClassNameForMeeting(item.meetingType);
      if (!!className) {
        return filtersToApply.indexOf(className) > -1;
      }
    });

    return {
      ...dateItem,
      meetings
    };
  }
}


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...