Angular 守卫服务注入服务。

3

我需要在守卫中注入一个服务。该守卫检查用户是否受邀请,如果是,则可以访问路由。

为了检查这个条件,我需要调用一个从数据库中获取此信息的服务。

我遇到了循环依赖错误。我知道我们不应该在守卫中注入服务,但在这种情况下,我必须这样做:

  providers: [AuthService, HackService, HacksStorageService, AuthGuard, EmailGuard],

并且警卫:
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate } from "../../../node_modules/@angular/router";
import { HacksStorageService } from "../shared/hacks-storage.service";

export class EmailGuard implements CanActivate {

  constructor(
    private hacksStorageService: HacksStorageService,
  ) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    this.hacksStorageService.fetchHack();
    // check if user was invited. should be in the participants array
    return true;
  }
}

我感到相当困惑。通常我使用guard来检查用户是否已经登录,因此我通常从Firebase导入东西,而不是从我的自己的服务中导入,所以没有循环依赖。

现在我想要根据自己的数据检查条件是否发生。如果由于循环依赖关系而无法注入服务,则该如何在EmailGuard中注入我的自己的数据呢?

谢谢。


“在EmailGuard中注入数据”是什么意思?同时,请将您的AuthGuard放置在路由模块中,而不是应用程序或任何功能模块中。 - Amit Chigadani
我想将hacksStorageService注入到我的EmailGuard中。我需要这样做,因为hacksStorageService有一个方法可以返回一个对象。一旦我有了这个对象,我就可以检查一个条件。 - AlbertMunichMar
1
你可以将服务注入到守卫中,这没有问题,但是你不能有循环依赖,所以你必须以一种不会发生循环依赖的方式解决它 :) - AT82
1
非常抱歉,我忘记了 @Injectable。当我发现我的守卫无法创建时,我立即想到了循环依赖。感谢大家的帮助,再次道歉。管理员们,我应该删除这个问题吗? - AlbertMunichMar
2个回答

4
你可以在守卫中注入服务。 如果你的服务是同步的,那么你可以像样例代码中一样立即返回。 否则,我会这样做(使用Firebase Auth)。
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { map, first } from 'rxjs/operators';
import { AngularFireAuth } from '@angular/fire/auth';
import { Paths } from './paths';

@Injectable({
  providedIn: 'root'
})
export class SignInGuard implements CanActivate {

  constructor(private afAuth: AngularFireAuth, private router: Router) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      return this.afAuth.user.pipe(
        first(),
        map(user => {
          if (user) {
            this.router.navigate([Paths.MAIN_PATH]);
            return false;
          } else {
            return true;
          }
        })
      );
  }
}

1
这个解决方案已经被弃用。更准确地说,CanActivate接口已经被弃用。 - fonzane
1
这个解决方案已经过时了。更准确地说,CanActivate接口已经被弃用了。 - undefined

0
当前的解决方案可以在这里找到:
const canActivateTeam: CanActivateFn = 
  (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
    return inject(PermissionsService).canActivate(inject(UserToken), route.params.id);
  };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接