因此,我声明了这个 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 中加入豁免,但这似乎很疯狂。
我想做的是检查更改路线时要解析的组件的名称,然后在与我的组件匹配的情况下隐藏预加载器。 有可能吗?
答案 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();
}
}