5

我想要完成的是每次应用程序初始化只调用一次外部 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. 我也想使用XServicewith ,每当我尝试从(通过)SecondComponent再次调用服务时, Angular 都会命中外部 API。我想尽量减少外部影响。SecondComponent_service._service.callAnAPI()

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

4

2 回答 2

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 ]);

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

于 2016-03-18T11:26:06.403 回答
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);
      }
    }
}
于 2016-03-18T11:25:46.383 回答