在我的角应用程序中,我使用CanActivate保护来保护特定路由器状态下的访问。
CanActivate守卫执行一个可以持续3-4秒的检查,在没有加载指示器(即旋转器)的情况下等待这段时间是非常烦人的。
在CanActivate检查期间,是否有一种“标准”方式来显示加载旋转器?
非常感谢
发布于 2018-02-18 04:47:05
要回答你的问题,没有“标准”的方法。
但这很容易。我通过以下操作解决了这个问题:
将AuthGuard服务导入app.component.ts文件:
import { Component, OnInit } from '@angular/core';
// Import AuthGuard service here - double check the path
import { AuthGuard } from './services/auth.guard';
@Component({
selector: 'body',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
// Inject AuthGuard service here
constructor(private authGuard: AuthGuard) { }
ngOnInit() { }
});将加载器HTML添加到app.component.html文件中:
<router-outlet></router-outlet>
<div class="central-loader" *ngIf="(authGuard.loader)"><div><i class="fa fa-spin fa-spinner"></i> Loading...</div></div>请注意上面的装载机*ngIf。这将检查authGuard.loader变量,如果该变量的值设置为true,则加载此HTML代码。
在AuthGuard文件中(在我的例子中是services/auth.guard.ts):
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable, Subject } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
private loader$ = new Subject<boolean>();
public loader = false;
constructor() {
this.loader$.debounceTime(300).subscribe(loader => {
this.loader = loader;
});
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
this.loader$.next(true);
// Returning an Observable for async checks
return new Observable<boolean>(obs => {
// Sample 2 second async request
setTimeout(() => {
this.loader$.next(false);
obs.next(true);
obs.complete();
}, 2000);
});
}
}您还可以使用loader$管道直接调用模板中的async,例如:
<router-outlet></router-outlet>
<div class="central-loader" *ngIf="(authGuard.loader$ | async)"><div><i class="fa fa-spin fa-spinner"></i> Loading...</div></div>(在本例中,将loader$设置为public )。
但是,如果canActivate检查在不到300 is内完成,我不希望这个加载程序出现,这就是为什么我使用debounceTime()订阅loader$的原因。
我知道,即使把false发送给观察者,也会延迟300 me,但这对我来说没什么关系。
顺便说一句,这是我在加载程序中使用的CSS,它以水平和垂直两种方式居中,并设置完整的页面阻塞覆盖:
.central-loader {
position: fixed;
display: flex;
width: 100vw;
height: 100vh;
background: rgba(0,0,0,0.2);
z-index: 1050;
}
.central-loader > div {
height: 42px;
line-height: 40px;
width: 200px;
text-align: center;
border: 2px #faf2cc solid;
color: #8a6d3b;
background-color: #fcf8e3;
margin: auto;
}不要忘记在AuthGuard中导入app.module.ts
import { NgModule } from '@angular/core';
....
// Import AuthGuard service here - double check the path
import { AuthGuard } from './services/auth.guard';
@NgModule({
....
providers: [
AuthGuard,
....
],
....
});我希望这能帮到你!
发布于 2020-10-22 07:21:58
试试这个,使用路由器事件。很简单。
<div class="loading-icon" *ngIf="loading"></div>在app.component.ts文件中:
this.router.events.subscribe(event => {
if (event instanceof GuardsCheckStart) {
this.loading = true;
console.log("GuardStart")
}
if (event instanceof GuardsCheckEnd || event instanceof NavigationCancel) {
this.loading = false;
console.log("GuardEnd")
}
});发布于 2018-07-25 08:57:17
您好,经过一段时间的环顾,我发现了这个,使用开始和点击这是使用的CanActivate卫队正在加载。
import { Injectable } from '@angular/core';
import * as firebase from 'firebase/app';
import { AngularFireAuth } from 'angularfire2/auth';
import { Observable, of } from 'rxjs';
import { switchMap, startWith, tap } from 'rxjs/operators';
import { User } from './user';
@Injectable({
providedIn: 'root'
})
export class AuthService {
user: Observable<User>;
constructor(private afAuth: AngularFireAuth,
private db: AngularFirestore) {
//// Get auth data, then get firestore user document || null
this.user = this.afAuth.authState.pipe(
switchMap(user => {
if (user) {
return this.db.doc<User>(`users/${user.uid}`).valueChanges()
} else {
return of(null)
}
}),
// Add these lines to set/read the user data to local storage
tap(user => localStorage.setItem('user', JSON.stringify(user))),
startWith(JSON.parse(localStorage.getItem('user')))
)
}
}请参阅"tap“& "startWith”函数,如果您有加载问题,请使用类似的方法。其他的一些评论是非常刻薄的(不要做无趣)
https://stackoverflow.com/questions/48486623
复制相似问题