在组件初始化之前执行GET请求

时间:2018-02-15 11:08:30

标签: angular typescript

我有这样的模板代码:

 <li *ngIf="isRoot() || isSoftware()">

我在组件代码中也有这个功能:

isRoot() {
    return this.service.Level == 'Root';
}

isSoftwareOnly() {
    return this.service.ServiceType == 'Software';
}

this.service通过HTTP请求获取。 如何在模板开始渲染之前获取请求?现在isRoot()isSoftware()总是返回false,因为this.service.Level和this.service.ServiceType是 undefined

3 个答案:

答案 0 :(得分:1)

我看到三种方式:

首先(最快):使用您组件的constructor(假设您在服务中使用fetchData方法发出http请求:

 export class Component {
     constructor(private service: MyService) {
          this.service.fetchData();
     }
 }

秒(较慢):使用ngOnInit挂钩 - 在视图初始化开始的同一时刻将获取数据。

第三:使用ngOnChanges生命周期钩子(在我看来,这不是你用例中的最佳做法) - 根据文档:

  

Angular(重新)设置数据绑定输入属性时的响应。该方法接收当前和先前属性值的SimpleChanges对象。   在ngOnInit()之前以及每当一个或多个数据绑定输入属性发生更改时调用。

More about lifecycle hooks in Angular

答案 1 :(得分:0)

您可以将整个模板包装在ng-container中,并在组件中有一个标志,一旦数据加载就设置为true:

export class MyComponent {
   dataHasLoaded: boolean = false;

   ngOnInit() {
       this.loadData();
   }

   loadData() {
   // send http-request
   this.httpService.getData().subscribe(() => {
       this.dataHasLoaded = true;
   })

在你的模板中:

<ng-container *ngIf="dataHasLoaded">
    <!-- the rest of your HTML -->
</ng-container>

这样,只有拥有数据后,html才会开始渲染。

答案 2 :(得分:0)

如果必须在组件初始化之前进行检查,那么执行该方法的最佳方法是Guards机制(guide here)。要创建一个防护,只需创建一个实现CanActivate接口的类。类的canActivate方法应该返回一个Observable,告诉路由器它是否可以加载路由。

因此,在激活包含组件的路径之前,您的警卫将确保您的GET XHR已返回。

类似(查看文档here

@Injectable()
class CanActivateCheckServiceState implements CanActivate {
  constructor(private myService: <YourService>) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {
    return this.myService.<yourGetMethod>
         .map(() => return true)
         .catch(() => return false)
  }
}

然后在路由配置中使用它:

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: '<yourPath>',
        component: <yourComponent>,
        canActivate: [CanActivateCheckServiceState]
      }
    ])
  ],
  providers: [CanActivateCheckServiceState, <yourService>]
})
class YourModule {}