Angular 2 resolver with loading indicator

筅森魡賤 提交于 2019-12-03 09:27:12

问题


I use resolvers to load the data into the components, but until the data is not returned from the server the component does not load. I would like to know if there is a way to render a load indicator before the server responds.


回答1:


You can use the "reacting to routing events" strategy that consist to implement the App to react when any routing event occurs. To do that, you will need in your app.component.ts some code like:

import { Component } from '@angular/core';
import { Router, RouterEvent, NavigationStart, NavigationEnd, NavigationError, NavigationCancel } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass']
})
export class AppComponent {

  loading: boolean = true;

  constructor(private router: Router) {
    router.events.subscribe((routerEvent: RouterEvent) => {
      this.checkRouterEvent(routerEvent);
    });
  }

  checkRouterEvent(routerEvent: RouterEvent): void {
    if (routerEvent instanceof NavigationStart) {
      this.loading = true;
    }

    if (routerEvent instanceof NavigationEnd ||
      routerEvent instanceof NavigationCancel ||
      routerEvent instanceof NavigationError) {
      this.loading = false;
    }
  }
}

And in the view(html) something like:

<div id="loader" class="myloader" *ngIf="loading">
  Loading...
</div>



回答2:


Another solution I came up with is using Observable<Observable<...>> in your resolvers:

// data-resolver.service.ts

// ...

export class DataResolverService implements Resolve<Observable<Data>> {

// ...

  resolve(route: ActivatedRouteSnapshot): Observable<Observable<Data>> {
    return of(this.client.get(...));
  }
}

Notice the usage of rxjs's of operator to construct an immediately completing Observable from your source Observable. Now you can easily handle your loading indicator in the component:

export class DashboardComponent {
  loading = true;
  error = false;

  data$: Observable<Data>;

  constructor(private activatedRoute: ActivatedRoute) {
    this.data$ = this.activatedRoute.data.pipe(switchMap((data) => data.data$));
    this.data$.subscribe(() => this.loading = false, () => this.error = true);
  }
}

See my in-depth medium story about this here. This is a real life example coming from my shift scheduling application tift.




回答3:


the simplest version is going to be an ngIf statement

wrap an image in an ngIf on a root level component.

use a service to set whether it is visible or not.

eg:

before sending request: call service function to set variable to true

then in the component that is loaded, have the first thing that it does is set that variable back to false




回答4:


You should use https://www.npmjs.com/package/angular2-busy

which Directly listen to your Api call

ngOnInit() {
        this.busy = this.http.get('...').subscribe();
    }

<div [ngBusy]="busy"></div>

This will show spinner until you get response from server.



来源:https://stackoverflow.com/questions/42048142/angular-2-resolver-with-loading-indicator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!