首页 > 解决方案 > 在 Angular 6 中的组件和服务之间共享变量

问题描述

我需要在 Angular 6 中实现加载/微调器图像。当 HTTP 服务发送请求时应该显示微调器,并在服务接收到响应时隐藏。

我在一个组件中实现了图像,注意loading变量:

@Component({
  selector: 'my-spinner',
  templateUrl: `
            <div class="center-all" *ngIf="loading">
                 <img src="spinner.gif"></img>
            </div> 
  `,
  styles: [ `
      .center-all {
          position: fixed; 
          top: 0; 
          left: 0;
          z-index: 99999;
          margin: -8px;
      }
  `],
})
export class MySpinnerComponent {}

我的 HTTP 服务应该直接更改loading变量(不通过声明MySpinnerComponent和调用 的父组件MyHttpService)。

@Injectable({
  providedIn: 'root'
})
export class MyHttpService {

    loading = false;

    constructor(private http: HttpClient) {}

    static handleError (error: Response) {
      console.error(error);
      return Observable.throw(error || 'Server error');
    }

    public call (params) {

       this.loading = true;  // how to share this variable with the spinner component?

        return this.http.post<any>(params.url, params.data).
          pipe(
              map(response => response),
              tap(this.loading = false),
              catchError(VbkHttpService.handleError)
          );
    }

}

在 AngularJS 中,我声明了变量,$rootScope以便我可以共享它。但是如何在 Angular 6 中实现等价物呢?

标签: angular

解决方案


将事件发射器添加到服务

loadingChange=new EventEmitter<boolean>();

每次更改字段时,使用;loading发出事件this.loadingChange.emit(this.loading)

并在微调器组件中订阅该事件发射器。

    @Component({
      selector: 'my-spinner',
      templateUrl: `
                <div class="center-all" *ngIf="loading">
                     <img src="spinner.gif"></img>
                </div> 
      `,
      styles: [ `
          .center-all {
              position: fixed; 
              top: 0; 
              left: 0;
              z-index: 99999;
              margin: -8px;
          }
      `],
    })
    export class MySpinnerComponent{

    loading=false;

    constructor(private service:MyService){
        this.myService.loadingChange.subscribe(flag=>this.loading=flag);
    }
}

或者

您也可以简单地将loading字段设为公开并直接从时间表访问它,如下所示:

服务:

public loading;

零件

  @Component({
      selector: 'my-spinner',
      templateUrl: `
                <div class="center-all" *ngIf="service.loading">
                     <img src="spinner.gif"></img>
                </div> 
      `,
      styles: [ `
          .center-all {
              position: fixed; 
              top: 0; 
              left: 0;
              z-index: 99999;
              margin: -8px;
          }
      `],
    })
    export class MySpinnerComponent{
    constructor(private service:MyService){
    }
}

我只是更喜欢“发射器”的方式


推荐阅读