угловой сервис готов флаг - PullRequest
0 голосов

я пытаюсь переписать мое приложение 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);
    }
}


Ответы [ 3 ]

1 голос
/ 31 мая 2019

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

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*/);
}
1 голос
/ 31 мая 2019

используйте 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)

        });
    }
0 голосов
/ 31 мая 2019

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

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