Как получить ajax-звонки по заказу, используя rxjs - PullRequest
0 голосов
/ 14 октября 2019

У меня в приложении два сервиса.

@Injectable()
export class SettingService {
    private settings = new BehaviorSubject<any[]>([]);

    constructor(private http: HttpClient) {
        this.loadSettings();
    }

    private loadSettings() {
        this.http.get<any[]>('/api/settings')
            .subscribe((settings) => this.settings.next(settings));
    }

    getSettings() {
        return this.settings.asObservable();
    }
}

@Injectable()
export class InformationService {
    private informations = new BehaviorSubject<any[]>([]);

    constructor(private http: HttpClient) {
        this.loadSettings();
    }

    private loadInformations(appId: string) {
        this.http.get<any[]>('/api/informations/appId')
            .subscribe((informations) => this.informations.next(informations));
    }

    getInformations(appId: string) {
        return this.informations.asObservable();
    }
}

И я использую эти экземпляры сервисов в контроллере приложения.

@Component({
  selector: 'calc',
  templateUrl: 'calc.component.html',
  styleUrls: ['calc.component.css']
})
export class CalcComponent {
   constructor(informationService: InformationService, settingsService: SettingService){
        // settingsService.getSettings()
        // and use settings.appId to get informations.
        // informationService.getInformations(settings.appId)
   }
}

Как позвонить в сервис по заказу? Я новичок в rxjs.

Ответы [ 3 ]

1 голос
/ 14 октября 2019

Ваш подход к этим объектам BehaviorSubjects не является наилучшей практикой.

Прежде всего, удалите все эти типы. Создайте интерфейс.

export interface Setting {
  // whatever comes here
}
export interface Information {
  // whatever comes here
}

Вам не нужен сервис для каждой конечной точки API, давайте создадим только 1 здесь. Вы включаете обе конечные точки в эту услугу. Они возвращают Observable.

@Injectable()
export class MyService {
    constructor(private http: HttpClient) {}

    public loadSettings(): Observable<Setting[]> {
        return this.http.get<Setting[]>('/api/settings');
    }

    private loadInformations(appId: string): Observable<Information[]> {
        return this.http.get<Information[]>('/api/informations/appId');
    }
}

Затем в вашем Компоненте вы можете сделать что-то вроде этого:

@Component({
  selector: 'calc',
  templateUrl: 'calc.component.html',
  styleUrls: ['calc.component.css']
})
export class CalcComponent {
   settings$: Observable<Setting[]>;
   informations$: Observable<Information[]>;

   constructor(private myService: MyService){
        this.settings$ = myService.loadSettings();
        this.informations$ = this.settings$.pipe(
          switchMap(settings => myService.loadInformations(myAppId)), // whereever myAppId comes from
        );
   }
}

Подписаться на него в вашем шаблоне с помощью асинхронного канала.

0 голосов
/ 14 октября 2019

Похоже, вы хотите, чтобы звонки loadSettings и loadInformation происходили в определенном порядке? Если вы хотите, чтобы они заканчивались одновременно, я бы выбрал forkJoin(loadSettings(), loadInformation()), это аналог Promise.all. Если вы хотите, чтобы все происходило в определенном порядке, я согласен с приведенным выше ответом switchMap. Я бы не сказал, что приведенная выше архитектура не является наилучшей практикой. Зависит от того, посмотрите здесь хорошую статью о различных шаблонах с HTTP https://angular -academy.com / angular-архитектура-лучшие практики /

/ Крис Норинг, Angular GDE

0 голосов
/ 14 октября 2019

Вы можете использовать rxjs switchMap оператор:

settingsService.getSettings().pipe(switchMap(res1 => {
    informationService.getInformations(res1.appId)
  }).subscribe(res2 => {
    console.log(res2)
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...