角钢6显示除一个组件外的每个组件的预载器

时间:2018-12-16 21:47:37

标签: angular

因此,我声明了这个 Spinner 组件,它只是一个简单的preloader CSS图形。 它位于我的 App 组件上,并检查是否正在加载任何htpp数据。 如果是,它将显示微调框。如果不是,那么它会隐藏微调框:

<div class="spinner-container" *ngIf="loading">
  <div class="spinner">
    <div class="bounce1"></div>
    <div class="bounce2"></div>
    <div></div>
  </div>
</div>

我现在遇到一种情况,当我们在某个组件上时根本不想显示微调器。 我确实尝试使用网址来做到这一点:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, NavigationEnd, RoutesRecognized } from '@angular/router';
import { Subscription } from 'rxjs';

import { SpinnerService } from '../services/spinner.service';

@Component({
  selector: 'pyb-spinner',
  templateUrl: './spinner.component.html',
  styleUrls: ['./spinner.component.scss']
})
export class SpinnerComponent implements OnInit, OnDestroy {
  loading: boolean;

  private widgetUrls: any[] = ['scenarios', 'questions', 'answers', 'results']
  private url: string

  private routeSubscription: Subscription
  private spinnerSubscription: Subscription

  constructor(
    private route: Router,
    private spinnerService: SpinnerService
  ) { }

  ngOnInit() {
    this.routeSubscription = this.route.events.subscribe(event => this.getCurrentUrl(event));
    this.spinnerSubscription = this.spinnerService.onLoadingChanged.subscribe(loading => this.showSpinner(loading));
  }

  ngOnDestroy() {
    if (this.routeSubscription) this.routeSubscription.unsubscribe();
    if (this.spinnerSubscription) this.spinnerSubscription.unsubscribe();
  }

  private showSpinner(loading: boolean) {
    if (this.url) {
      let urlSegments = this.url.split('/');
      if (urlSegments.length > 1) {
        let lastSegment = urlSegments[urlSegments.length - 1];
        let index = this.widgetUrls.indexOf(lastSegment);

        if (index > -1) {
          this.loading = false;
          return;
        }
      }
    }

    this.loading = loading;
  }

  private getCurrentUrl(event: any) {
    if (event instanceof RoutesRecognized) {
      this.url = event.url;
    }
  }
}

但是在我的情况下,这是行不通的,因为我的组件具有这样的路由:

const widgetRoutes: Routes = [
  { path: ':category', redirectTo: ':category/scenarios', pathMatch: 'full', data: { state: 'widget' } },
  { path: ':category/:path', component: WidgetComponent, data: { state: 'widget' } }
];

例如,您可以转到/cameras,它将显示我的预加载器,但我不希望这样做。 我可以在每个类别的 SpinnerComponent 中加入豁免,但这似乎很疯狂。

我想做的是检查更改路线时要解析的组件的名称,然后在与我的组件匹配的情况下隐藏预加载器。 有可能吗?

2 个答案:

答案 0 :(得分:2)

您可以使用属性“数据”向所有不需要旋转器的路线添加属性“ noSpinner”

{ path: ':category/:path', 
  component: WidgetComponent, 
  data: { state: 'widget',noSpinner:true } 
}

如果您订阅了activatedRoute.data,那么您将获得值;如果!res.noSpinner,则订阅了onLoadingChange

this.activatedRoute.data.subscribe(res=>{
     console.log(res)
     if (!res.noSpinner)
          this.spinnerSubscription = this.spinnerService.onLoadingChanged
            .subscribe(loading => this.showSpinner(loading));
    })

好吧,实际上您可以使用switchMap仅获得一个订阅

this.spinnerSubscription = this.activatedRoute.data.pipe(
     switchMap(res=>{
       console.log(res)
       if (!res.noSpinner)
          return this.spinnerService.onLoadingChanged
       else 
          return of(false);
     }))
     .subscribe(loading => this.showSpinner(loading));

答案 1 :(得分:0)

我将扩大Eliseo的答案。他说的没错,但这只是部分答案。 实际的答案是将我的 ngOnInit 更改为此:

ngOnInit() {
  this.spinnerSubscription = this.router.events
    .pipe(
      filter(event => event instanceof NavigationEnd),
      map(() => this.activatedRoute),
      map(route => route.firstChild),
      switchMap(route => route.data),
      switchMap(data => {
        if (!data.disableSpinner)
          return this.spinnerService.onLoadingChanged
        else 
          return of(false);
      })
    ).subscribe(loading => this.loading = loading);
}

完成此操作后,我可以像这样使用我的路线中的数据:

const routes: Routes = [
  { path: '', redirectTo: '/', pathMatch: 'full' }, // Put first so it redirects :)
  { path: '', component: HomeComponent, data: { state: 'home' } },

  // Lazy load
  { path: '', loadChildren: './widget/widget.module#WidgetModule', data: { state: 'widget', disableSpinner: true } }, // Put this last as it has empty path

  // 404
  { path: '**', component: HomeComponent }, // 404?
]

这里要注意的一件事;如果您使用的是延迟加载,则必须确保数据对象是初始声明的一部分。 我确实在我的小部件路由模块中声明了data对象,但该对象被忽略了。

希望这对其他人有帮助。

PS:请确保这实际上可以帮助其他人;这是我的整个组件:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
import { Subscription, of } from 'rxjs';

import { SpinnerService } from '../services/spinner.service';
import { switchMap, filter, map } from 'rxjs/operators';

@Component({
  selector: 'pyb-spinner',
  templateUrl: './spinner.component.html',
  styleUrls: ['./spinner.component.scss']
})
export class SpinnerComponent implements OnInit, OnDestroy {
  loading: boolean;

  private spinnerSubscription: Subscription

  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private spinnerService: SpinnerService
  ) { }

  ngOnInit() {
    this.spinnerSubscription = this.router.events
      .pipe(
        filter(event => event instanceof NavigationEnd),
        map(() => this.activatedRoute),
        map(route => route.firstChild),
        switchMap(route => route.data),
        switchMap(data => {   
          if (!data.disableSpinner)
            return this.spinnerService.onLoadingChanged
          else 
            return of(false);
        })
      ).subscribe(loading => this.loading = loading);
  }

  ngOnDestroy() {
    if (this.spinnerSubscription) this.spinnerSubscription.unsubscribe();
  }
}