【问题标题】:Angular 2 call service only on app initializationAngular 2 仅在应用初始化时调用服务
【发布时间】:2023-03-09 09:32:01
【问题描述】:

我想要完成的是每次应用初始化只调用一次外部 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再次调用服务

【问题讨论】:

    标签: angular angular2-services angular2-injection


    【解决方案1】:

    您可以为此使用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 ]);
    

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

    【讨论】:

    • 如何在 Angular 2.2 中引导这个服务?
    【解决方案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);
          }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-03-31
      • 2016-07-23
      • 1970-01-01
      • 2015-08-12
      • 1970-01-01
      • 2015-09-15
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多