首页 > 解决方案 > Angular:组件不会使用来自公共服务变量的数据进行更新

问题描述

由于这个应用程序中的项目并不多Source,我想我会很聪明地设计一个服务,它也充当存储库,并在服务添加、更新或删除项目时在内部进行更新。

为了在第一次使用时填充存储库,我的主要组件然后listSources()通过订阅它运行一次。所有其他组件都注入了服务,并且在它们的模板中我let source of sourceService.sources用来获取源代码。

但是,当我通过addSource()或任何其他方式更改源时,这些更改不会反映在我的其他组件中。我也尝试过使用一个主题,但这变得更加混乱并且对我也不起作用。

有人知道我在做什么错吗?

这是服务:

export class SourceService { // truncated for brevity
  public sources: Source[] = [];

  constructor( ) { } 

  public listSources(): Observable<Source[]> {
    // if sources are already loaded, just return from memory
    if (this.sources.length > 0) {
      return of(this.sources);
    }

    return this.http.get<Source[]>(sourceUrl, httpOptions).pipe(
        tap(sources => {
        sources.forEach((source, index, sources) => {
          this.sources.push(source);
        });
        });
  }

  public addSource(source: Source): Observable<Source> {
    return this.http.post<Source>(sourceUrl, source, httpOptions).pipe(
      tap(data => {
        // update memory
        this.sources.push(Object.assign(new Source(), Source.EMPTY_MODEL));
      })
    );
  }

在其他地方,已sourceService注入的组件具有以下模板:

<mat-option *ngFor="let source of sourceService.sources" [value]="source.id">{{ source.title }}</mat-option>

标签: angular

解决方案


尝试这个

export class SourceService { // truncated for brevity
  public sources: Source[] = [];
  public sources$ = new BehavoiurSubject<Source[]>([]);
  constructor( ) { } 

  public listSources(): Observable<Source[]> {
    // if sources are already loaded, just return from memory
    if (this.sources.length) {
      this.sources$.next(this.sources);
      return of(this.sources);
    }

    return this.http.get<Source[]>(sourceUrl, httpOptions).pipe(
        tap(sources => {
        sources.forEach((source, index, sources) => {
          this.sources.push(source);
        });
        this.sources$.next(this.sources);
        });
  }

  public addSource(source: Source): Observable<Source> {
    return this.http.post<Source>(sourceUrl, source, httpOptions).pipe(
      tap(data => {
        // update memory
        this.sources.push(Object.assign(new Source(), Source.EMPTY_MODEL));
        this.sources$.next(this.sources);
      })
    );
  }

在你的组件中

    <ng-container *ngIf="sourceService.sources$ | async as sources>
      <mat-option *ngFor="let source of sources" [value]="source.id">{{ source.title }}</mat-option> 
    </ng-container >

推荐阅读