角度服务就绪标志

时间:2019-05-30 20:52:30

标签: angular rxjs

我正在尝试将我的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 个答案:

答案 0 :(得分:1)

使用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)

        });
    }

答案 1 :(得分:1)

有多种选择,但是我会从init方法返回一个Observable,尽管我更喜欢在我的返回observable或promise的方法中添加后缀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*/);
}

答案 2 :(得分:0)

如果您只想分配一个可以使用this.ready = Observable.of(true);并从import { Observable } from 'rxjs';开始的Observable导入值,我不确定您打算如何使用“ ready”