Использование rxjs для создания «сложного» объекта с использованием операторов комбинации - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь выяснить, как преобразовать общий итерационный шаблон в реактивные rxjs.Допустим, я пытаюсь создать объект с именем SchoolSchedule, состоящий из выходных и отпуска.

class SchoolSchedule {
  schoolName: string;
  districtName: string;
  singleDaysOff: Array<moment.Moment> = new Array<moment.Moment>();
  vacations: Array<Vacation> = new Array<Vacation>();

  constructor(schoolName: string, districtName: string) {
    this.schoolName = schoolName;
    this.districtName = districtName;
  }
}

class Vacation {
  startDate: moment.Moment;
  endDate: moment.Moment;

  constructor(startDate: moment.Moment, endDate: moment.Moment) {
    this.startDate = startDate;
    this.endDate = endDate;
  }
}

Я создаю экземпляры этого класса из файла json

{
  "daysOff": [
    {
      "name": "Your Elementary",
      "district": "Some County",
      "single": ["9/3", "11/12", "1/21"],
      "vacations": ["11/21-11/23", "12/20-1/4", "2/18-2/22"] 
    }
    ...
  ]
}

В не-реактивная логика, я анализирую каждый элемент JSON.Сначала я создаю экземпляр SchoolSchedule.Затем я анализирую подпункты 'single' и 'каникулы', чтобы заполнить экземпляр SchoolSchedule.Как мне сделать это с помощью комбинации наблюдаемых реактивным способом?

Это то, что я придумал до сих пор:

import { Observable, of, from, zip } from 'rxjs';
import { switchMap, map } from 'rxjs';
import moment from 'moment';

import DAYS_OFF from 'days_off.json';

const schoolSchedules = new Array<SchoolSchedule>();
const daysOffBySchool = from(DAYS_OFF['daysOff']).pipe(
  switchMap((schoolDayOffsJSON) => zip( 
    new Observable((observer) => {
       const schoolSchedule = new SchoolSchedule(schoolDayOffsJSON.name, schoolDayOffsJSON.district);
       observer.next(schoolSchedule);
       observer.complete();
    }),
    zip(
      from(schoolDayOffsJSON.single).pipe(
        switchMap((dateStr: string) => {
           return new Observable((observer) => {
              observer.next(moment(dateStr + '/2019', 'M/D/YYYY'));
              observer.complete();
           })
        })
      )
    ), 
    zip(
      from(schoolDayOffsJSON.single).pipe(
        map((dateRangeStr: string) => dateRangeStr.split('-')),
        switchMap(dateStr: string) => zip(
          return new Observable((observer) => {
              observer.next(moment(dateStr + '/2019', 'M/D/YYYY'));
              observer.complete();
          }),
          return new Observable((observer) => {
              observer.next(moment(dateStr + '/2019', 'M/D/YYYY'));
              observer.complete();
          })
        )),
        map((dateRanges: Array<moment.Moment>) => return new Vacation(dateRanges(0), dateRanges(1)))
      )
    )
  )),
  map((results) => {
    const schoolSchedule: SchoolSchedule = results[0];
    const singleDaysOff: Array<moment.Moment> = results[1];
    const vacations: Array<Vacation> = results[2];
    schoolSchedule.singleDaysOff = singleDaysOff;
    return schoolSchedule;
  }),
);
daysOffBySchool.subscribe((schoolSchedule: SchoolSchedule) => schoolSchedules.push(schoolSchedule));

Излишне говорить, что это не такРабота.Это сложный вопрос, но что я делаю не так?Что мне делать?Я понимаю, что было бы намного проще, если бы я не разбил это на кучу наблюдаемых, но я чувствую, что не смогу избежать этого паттерна с более сложной логикой позже;так что лучше сделать все правильно - прямо сейчас.

...