Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度:组件不会使用来自公共服务变量的数据进行更新_Angular - Fatal编程技术网

Angular 角度:组件不会使用来自公共服务变量的数据进行更新

Angular 角度:组件不会使用来自公共服务变量的数据进行更新,angular,Angular,由于这个应用程序中没有太多的Source项目,我想我应该聪明一点,设计一个服务,它也可以作为存储库,在服务添加、更新或删除项目时进行内部更新 为了在第一次使用时填充存储库,我的主组件然后通过订阅来运行一次listSources()。所有其他组件都注入了服务,我在它们的模板中使用let source of sourceService.sources来获取源代码 但是,当我通过addSource()或任何其他方式更改源代码时,这些更改不会反映在我的其他组件中。我也试着使用一个主题,但这让我更加困惑,

由于这个应用程序中没有太多的
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));
      })
    );
  }
试试这个

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);
      })
    );
  }
export-class-SourceService{//为简洁起见被截断
公共来源:来源[]=[];
公共资源$=新的行为主体([]);
构造函数(){}
public listSources():可观察{
//如果源已经加载,只需从内存返回即可
if(this.sources.length){
this.sources$.next(this.sources);
归还(本资料来源);
}
返回此.http.get(sourceUrl,httpOptions).pipe(
点击(来源=>{
sources.forEach((源、索引、源)=>{
this.sources.push(source);
});
this.sources$.next(this.sources);
});
}
public addSource(source:source):可观察{
返回此.http.post(sourceUrl,source,httpOptions).pipe(
点击(数据=>{
//更新内存
this.sources.push(Object.assign(newsource(),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 >

你能告诉我们你在哪里注入服务吗?当然可以;我正在将它传递给我的app.module文件中的构造函数和提供者部分,所以目前为止,你的方法没有发现任何问题。如果可能的话,请你创建plunkrindeed。我做的一切都是正确的,但调用了错误的函数。很抱歉浪费你的时间:(谢谢Sai。我刚刚解决了我的问题,这完全是愚蠢的:我调用了一个与我想象中不同的函数。但是你的解决方案让我很感兴趣。我见过主题的使用,但我并不真正理解这种情况下的不同。你最初的解决方案应该有效。因为你没有提供plunker,我不确定从服务到组件的数据流。使用主题将始终确保组件中的数据是最新的
    <ng-container *ngIf="sourceService.sources$ | async as sources>
      <mat-option *ngFor="let source of sources" [value]="source.id">{{ source.title }}</mat-option> 
    </ng-container >