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

Mar*_*rty 5 angular2-services angular2-injection angular

我想要完成的是每个应用程序初始化只调用一次外部 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

和两个组件,主要 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}
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

export class SecondComponent {

    constructor(private _service: XService){

    }
}
Run Code Online (Sandbox Code Playgroud)

服务被初始化,Angular 在AppComponent. 我也想使用XServicewith SecondComponent,每当我尝试从SecondComponent, (via _service._service.callAnAPI()) Angular再次调用服务时,都会命中外部 API。我想尽量减少外部点击。

我如何获取AppComponent初始化所做的数据而不是再次调用服务SecondComponent

Thi*_*ier 4

您可以使用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;
        });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

bootstrap(AppComponent, [ XService ]);
Run Code Online (Sandbox Code Playgroud)

这样,您将为整个应用程序使用单个实例。