在多个组件之间共享来自单个实例服务的数据(和缓存)

时间:2018-12-14 16:54:02

标签: angular typescript

我正在创建一个服务,该服务将从服务器中提取数据,然后将该数据加载到稍后使用的属性中,然后通知所有组件该服务“就绪”。将数据加载到属性中的想法是使组件可以同步查询数据(通过某些方法) 我遇到的问题是每个组件都会触发一个新的http调用。

所以问题是我如何仅发出一个http请求,然后在数据“就绪”时通知所有组件??

@Injectable({
    providedIn: 'root'
})
export class TypelistService {
    private readonly baseURL = `${environment.myEndpoint}/api/typelist`;
    private list: Type[];
    private iSeeYou: Observable<ServiceStatus>;
    constructor(private http: HttpClient) {
        console.log('Hello Constructor'); // <-- this line execute only once as expected
        this.iSeeYou = new Observable((observer) => {
            observer.next({ status: 'calling' });
            this.http.get(this.baseURL).subscribe((data: Type[]) => {
                this.list = data;
                observer.next({ status: 'ready' });
                observer.complete();
            });
        });
    }

    init(): Observable<ServiceStatus> {
        return this.iSeeYou;
    }
    getAllTypes() {
        return this.list;
    }
    getItemById(id: number): Type {
        let item: TypeError;
        this.list.forEach((i) => {
            if (i.id === id) {
                item = i;
            }
        });
        return item;
    }
    getItemByName(name: string): Type {
        let item: TypeError;
        this.list.forEach((i) => {
            if (i.name === name) {
                item = i;
            }
        });
        return item;
    }
}

1 个答案:

答案 0 :(得分:1)

如果要让其他组件知道可用数据并准备就绪。您可以在服务中将list声明为BehaviourSubject。这样,每次列表中发生更改或更新时,每个订户都会得到通知并获得最新的可用值。

EX:

listData: BehaviorSubject<Type[]> = new BehaviorSubject([]);

,然后在收到数据后将其返回为Observable:

iSeeYou() {
//make service call get the data and push to list
        this.listData.next(data);
    }

您可以将列表公开给其他人观察,以使其他组件不会与Subject值混淆:

list = this.listData.asObservable();

现在,您可以订阅组件中的列表,并在列表更改后立即获取更新。所有订户将具有列表中的最新值。

详细了解BehaviorSubjects here