Флаг готовности службы angular

я пытаюсь переписать свое приложение angularJS на angular2 поэтому у меня есть сервис, который загружает метки i18n с разных конечных точек. и мне нужно знать, когда все данные будут готовы.

в моих компонентах angularJS я могу сделать так

vm.loading = true;
backend.ready.then(() => {
   loading = false;
   backend.getAlias('anyLabel')
})

поэтому при загрузке === false я скрываю загрузчик и могу получить псевдонимы Но я не могу понять, как это сделать с помощью сервисов angular2 и наблюдаемых объектов. Теперь у меня есть что-то вроде этого:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, zip, of, Subject } from 'rxjs';

export interface Alias {
    code: string;
    value: string;
}

@Injectable({
    providedIn: 'root'
})
export class BackendService {
    private aliases: Alias[];
    private aliasDeclaration: Alias[];
    public ready: Observable<boolean>;

    constructor(private http: HttpClient) {
        this.aliases = [];
        this.aliasDeclaration = [];
        this.ready = new Observable<boolean>();
    }

    private getAliases(): Observable<Alias[]> {
        return this.http.get<Alias[]>('/json/get-aliases?lang=ru');
    }

    private getDeclarations(): Observable<Alias[]> {
        return this.http.get<Alias[]>('/themes/backend/aliases-declaration.json');
    }

    public init(): void {
        zip(this.getAliases(), this.getDeclarations()).subscribe(([aliases, declarations]) => {
            this.aliases = aliases;
            this.aliasDeclaration = declarations;
            // i need to set ready = true here, but can't figure out how :)
        });
    }

    public getAlias(code): Alias {
        return this.aliases.find(alias => alias.code === code);
    }

    public getAliasDeclaration(code): Alias {
        return this.aliasDeclaration.find(alias => alias.code === code);
    }
}


Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
410
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

используйте behaviorSubject

public ready= new BehaviorSubject(false);

сделать готовым излучать

public init(): void {
        zip(this.getAliases(), this.getDeclarations()).subscribe(([aliases, declarations]) => {
            this.aliases = aliases;
            this.aliasDeclaration = declarations;
            // i need to set ready = true here, but can't figure out how :)
this.ready.next(true)

        });
    }

Выглядит довольно легко, спасибо! Я думаю, мне нужно прочитать некоторую документацию

Евгений Литвиненко 30.05.2019 23:10

Вы также можете подумать о make private _ready = new BehaviorSubject(false); public ready = this._ready.asObservable(); - тогда вы будете уверены, что никто другой не сможет передать новое значение в _ready, но все смогут его прочитать.

Maxim Georgievskiy 11.12.2019 20:33

Я не уверен, что вы хотите делать с «готовым», если вы просто хотите присвоить значение, которое вы можете использовать this.ready = Observable.of(true);, и добавить импорт для Observable из import { Observable } from 'rxjs';

я просто пытаюсь убедиться (в своих компонентах), что все мои псевдонимы загружены, и компонент может использовать их, а также показывать/скрывать загрузчик и другие вещи.

Евгений Литвиненко 30.05.2019 23:08

Существуют различные варианты, но я бы вернул Observable из метода init, хотя я предпочитаю добавлять суффикс Async к своим методам, которые возвращают Observable или обещание.

import { shareReplay, map } from 'rxjs/operators';
public initAsync(): Observable<BackendService> {
    const merged = zip(this.getAliases(), this.getDeclarations()).pipe(shareReplay());

    merged.subscribe(([aliases, declarations]) => {
        this.aliases = aliases;
        this.aliasDeclaration = declarations;
    // i need to set ready = true here, but can't figure out how :)
    });
    return merged.pipe(map(() => this));
}

shareReplay гарантирует, что будет использоваться один и тот же результат. Я также возвращаю сам сервис из Observable, хотя в этом нет необходимости. Это позволяет подписчику легко использовать услугу, которая уже готова, но вернуть все, что вы хотите.

Телефонный код

ngOnInit() {
  this.service.initAsync().subscribe(_ => /*do something*/);
}

Другие вопросы по теме