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

时间:2016-03-18 11:23:14

标签: angular angular2-services angular2-injection

我想要完成的是每个应用初始化只调用一次外部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初始化时命中服务器。我也希望XService同时使用SecondComponent,每当我尝试再次从SecondComponent调用服务时,(通过_service._service.callAnAPI())Angular会点击外部API。我想尽量减少外部命中。

如何在初始化时获取AppComponent所做的数据,而不是再次在SecondComponent中再次调用该服务

2 个答案:

答案 0 :(得分: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;
        });
    }
  }
}

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

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

bootstrap(AppComponent, [ XService ]);

这样您就可以在整个应用程序中使用单个实例。

答案 1 :(得分:2)

@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);
      }
    }
}