首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在CanActivate期间显示加载指示符

在CanActivate期间显示加载指示符
EN

Stack Overflow用户
提问于 2018-01-28 13:00:04
回答 3查看 7.9K关注 0票数 22

在我的应用程序中,我使用CanActivate保护来保护特定路由器状态下的访问。

CanActivate守卫执行一个可以持续3-4秒的检查,在没有加载指示器(即旋转器)的情况下等待这段时间是非常烦人的。

在CanActivate检查期间,是否有一种“标准”方式来显示加载旋转器?

非常感谢

EN

回答 3

Stack Overflow用户

发布于 2018-02-18 04:47:05

要回答你的问题,没有“标准”的方法。

但这很容易。我通过以下操作解决了这个问题:

将AuthGuard服务导入app.component.ts文件:

代码语言:javascript
运行
复制
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文件中:

代码语言:javascript
运行
复制
<router-outlet></router-outlet>
<div class="central-loader" *ngIf="(authGuard.loader)"><div><i class="fa fa-spin fa-spinner"></i>&nbsp; Loading...</div></div>

请注意上面的装载机*ngIf。这将检查authGuard.loader变量,如果该变量的值设置为true,则加载此HTML代码。

在AuthGuard文件中(在我的例子中是services/auth.guard.ts):

代码语言:javascript
运行
复制
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,例如:

代码语言:javascript
运行
复制
<router-outlet></router-outlet>
<div class="central-loader" *ngIf="(authGuard.loader$ | async)"><div><i class="fa fa-spin fa-spinner"></i>&nbsp; Loading...</div></div>

(在本例中,将loader$设置为public )。

但是,如果canActivate检查在不到300 is内完成,我不希望这个加载程序出现,这就是为什么我使用debounceTime()订阅loader$的原因。

我知道,即使把false发送给观察者,也会延迟300 me,但这对我来说没什么关系。

顺便说一句,这是我在加载程序中使用的CSS,它以水平和垂直两种方式居中,并设置完整的页面阻塞覆盖:

代码语言:javascript
运行
复制
.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

代码语言:javascript
运行
复制
import { NgModule } from '@angular/core';

....

// Import AuthGuard service here - double check the path
import { AuthGuard } from './services/auth.guard';

@NgModule({
    ....
    providers: [
        AuthGuard,
        ....
    ],
    ....
});

我希望这能帮到你!

票数 29
EN

Stack Overflow用户

发布于 2020-10-22 07:21:58

试试这个,使用路由器事件。很简单。

代码语言:javascript
运行
复制
<div class="loading-icon" *ngIf="loading"></div>

app.component.ts文件中:

代码语言:javascript
运行
复制
    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")
      } 
    });
票数 20
EN

Stack Overflow用户

发布于 2018-07-25 08:57:17

您好,经过一段时间的环顾,我发现了这个,使用开始和点击这是使用的CanActivate卫队正在加载。

代码语言:javascript
运行
复制
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”函数,如果您有加载问题,请使用类似的方法。其他的一些评论是非常刻薄的(不要做无趣)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48486623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档