Angular 2 仅在应用程序初始化时调用服务

Angular 2 call service only on app initialization

我想要完成的是每次应用程序初始化只调用一次外部 API。

我有一个简单的服务,

@Injectable()
export class XService {
    url = "http://api.example.com"
    constructor(private _http:Http) {

    }

    callAnAPI(){
        console.log('made an external request");
        return this._http.get(url)
            .map(res=>res.json());
    }
}

还有两个组成部分,主要appComponent

@Component({
  selector: 'my-app',
  template: `
    <div>
      Test
    </div>
  `
})

export class AppComponent {
    isLoading = true;
    results = [];

    constructor(private _service: XService){

    }

    ngOnInit(){
        Observable.forkJoin(
            this._service.callAnAPI()
            // some more services here
        )
        .subscribe(
            res => {
                this.results = res[0];
            },
            null,
            () => {this.isLoading = false}
        );
    }
}

和另一个与路由一起使用的组件

@Component({
  template: `
    <div>
      I want to use the service with this component.
    </div>
  `
})

export class SecondComponent {

    constructor(private _service: XService){

    }
}

服务已初始化,Angular 在 AppComponent 初始化时访问服务器。我也想将 XServiceSecondComponent 一起使用,每当我尝试从 SecondComponent 再次调用该服务时,(通过 _service._service.callAnAPI())Angular 会点击外部 API。我想尽量减少外部点击。

如何在初始化时获取 AppComponent 生成的数据,而不是在 SecondComponent

中再次调用该服务
@Injectable()
export class XService {
    url = "http://api.example.com"
    constructor(private _http:Http) {

    }

    callAnAPI(){
      if(this.data) {
        return Observable.of(this.data);
      } else {
        console.log('made an external request");
        return this._http.get(url)
            .map(res=>res.json())
            .do(res => this.data = res);
      }
    }
}

您可以为此使用 do 运算符来第一次获取数据并在下次调用时重复使用它们:

@Injectable()
export class XService {
  url = "http://api.example.com"
  constructor(private _http:Http) {

  }

  callAnAPI(){
    console.log('made an external request");
    if (this.cachedData) {
      return Observable.of(this.cachedData);
    } else {
      return this._http.get(url)
        .map(res=>res.json())
        .do((data) => {
          this.cachedData = data;
        });
    }
  }
}

如果要在启动时加载数据,可以从服务构造函数中调用callAnAPI方法。

为了能够使用这种方法,您需要在引导应用程序时定义您的服务:

bootstrap(AppComponent, [ XService ]);

这样您就可以为整个应用程序使用一个实例。