Angular 角度法不保存变量值

Angular 角度法不保存变量值,angular,angular-router-guards,angular-route-guards,Angular,Angular Router Guards,Angular Route Guards,我正在创建一个角度的路线守卫;它的工作原理取决于你是否与一家公司有关联;它会将您发送到特定组件。Unfourtnetly在运行canLoad方法时,它不会保存companieslist变量的值。任何帮助都将不胜感激 import { Injectable } from '@angular/core'; import { CanActivate, Router, CanLoad } from '@angular/router'; import { AuthService } from 'src/a

我正在创建一个角度的路线守卫;它的工作原理取决于你是否与一家公司有关联;它会将您发送到特定组件。Unfourtnetly在运行canLoad方法时,它不会保存companieslist变量的值。任何帮助都将不胜感激

import { Injectable } from '@angular/core';
import { CanActivate, Router, CanLoad } from '@angular/router';
import { AuthService } from 'src/app/auth.service';
import { User } from 'src/models/user';
import {ListdataService} from 'src/app/listdata.service';

@Injectable({
  providedIn: 'root'
})
export class CompanyonlyService implements CanActivate, CanLoad {
  companieslist=[];

  constructor(private authService: AuthService, private router: Router,private dataService:ListdataService) { }



  run(){
    this.dataService.sendGetRequestcompanies().subscribe((data: any[])=>{
      let tmp = [];

      for (let key in data)
        if (data.hasOwnProperty(key))
          tmp.push(data[key])

          this.companieslist = tmp;
          console.log(this.companieslist)





    }   )}



  canActivate() {
    return this.canLoad()
  }


    //this method won't set the value of the variable why?
    canLoad(){

      this.run()
      console.log('after loop')
      console.log(this.companieslist)
    if (this.companieslist.length==0) {

      this.router.navigate(['/companysignup']);

    }
    else{
      this.router.navigate(['/dashboard']);
    }

    return this.authService.isLoggedIn();
  } 
  }



[在此处输入图像描述]这是我在控制台中返回的内容

由于请求,方法运行是异步的,您没有检查请求是否已完成

因此,如果请求在检查条件时未完成,CompanyList的大小将始终等于0


选中此项

由于请求的原因,方法运行是异步的,您没有检查请求是否已完成

因此,如果请求在检查条件时未完成,CompanyList的大小将始终等于0


选中此项

问题是基于异步的。run方法运行影响campaniesList数组的订阅。但是,当您调用run并启动订阅时,它不会停止执行您的代码。因此,当您在运行后立即登录时:

  this.run()
  console.log('after loop')
  console.log(this.companieslist)
它在订阅块中嵌套的内容之前运行:

 this.dataService.sendGetRequestcompanies().subscribe((data: any[])=>{
  let tmp = [];

  for (let key in data)
    if (data.hasOwnProperty(key))
      tmp.push(data[key])

      this.companieslist = tmp;
      console.log(this.companieslist)
}
编辑:

我所配备的防护装置示例

 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
   return this.userService.getPermissions(this.userService.userId).pipe(map((permissions: string[]) => {
       if(permissions.length === 0) {
            this.router.navigateByUrl('/dashboard');
       }
       return permissions.length > 0; // this is where you could check for some specific permission maybe?
   }),
   retry(3),
   catchError(() => {
    this.router.navigateByUrl('/dashboard');
    return of(false);
   })
canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察{
返回this.userService.getPermissions(this.userService.userId).pipe(映射((权限:字符串[]))=>{
if(permissions.length==0){
this.router.navigateByUrl('/dashboard');
}
return permissions.length>0;//这是您可以检查某些特定权限的地方?
}),
重试(3),
捕获错误(()=>{
this.router.navigateByUrl('/dashboard');
归还(假);
})

问题是基于异步的。run方法运行影响campaniesList数组的订阅。但是,当您调用run并触发订阅时,它不会停止执行代码。因此,当您在运行后立即登录时:

  this.run()
  console.log('after loop')
  console.log(this.companieslist)
它在订阅块中嵌套的内容之前运行:

 this.dataService.sendGetRequestcompanies().subscribe((data: any[])=>{
  let tmp = [];

  for (let key in data)
    if (data.hasOwnProperty(key))
      tmp.push(data[key])

      this.companieslist = tmp;
      console.log(this.companieslist)
}
编辑:

我所配备的防护装置示例

 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
   return this.userService.getPermissions(this.userService.userId).pipe(map((permissions: string[]) => {
       if(permissions.length === 0) {
            this.router.navigateByUrl('/dashboard');
       }
       return permissions.length > 0; // this is where you could check for some specific permission maybe?
   }),
   retry(3),
   catchError(() => {
    this.router.navigateByUrl('/dashboard');
    return of(false);
   })
canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察{
返回this.userService.getPermissions(this.userService.userId).pipe(映射((权限:字符串[]))=>{
if(permissions.length==0){
this.router.navigateByUrl('/dashboard');
}
return permissions.length>0;//这是您可以检查某些特定权限的地方?
}),
重试(3),
捕获错误(()=>{
this.router.navigateByUrl('/dashboard');
归还(假);
})

CanLoad guard的方法类型签名允许您返回一个
可观察的
、一个
承诺
,或者只是一个普通的
布尔值

CanActivate guard与之类似,只是您可以返回
布尔值
UrlTree
,但仍然允许它是可观察的或承诺的。这意味着该函数可以等待您的调用完成

出于您的目的,CanActivate就足够了,除非您想阻止客户端完全加载不同的路由模块,但这超出了本答案的范围

您的dataService请求返回一个可观察的数据,因此您需要做的就是将请求返回的数据映射到CanActivate的正确返回类型

以下是一种方法:

import { Injectable } from '@angular/core';
import { CanActivate, Router, CanLoad } from '@angular/router';
import { map } from 'rxjs/operators';
import { AuthService } from 'src/app/auth.service';
import { User } from 'src/models/user';
import { ListdataService } from 'src/app/listdata.service';

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

  constructor(private authService: AuthService, private router: Router,private dataService:ListdataService) { }

  canActivate() {
    return this.dataService.sendGetRequestcompanies().pipe(
      map((data: any[]) => {
        if(data && data.length > 0) return this.router.createUrlTree(['/dashboard']);
        else return this.router.createUrlTree(['/companysignup']);
      })
    );
  }

}
使用Typescript的一个主要优点是知道参数的类型或返回类型。如果不正确声明它们,则无法将您从自己手中解救出来,并且您错过了可以返回的不同选项

全类型方法将是:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean|UrlTree> | Promise<boolean|UrlTree> | boolean|UrlTree {
    return this.dataService.sendGetRequestcompanies().pipe(
      map((data: any[]) => {
        if(data && data.length > 0) return this.router.createUrlTree(['/dashboard']);
        else return this.router.createUrlTree(['/companysignup']);
      })
    );
  }
canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察的|承诺|布尔| UrlTree{
返回此.dataService.sendGetRequestCompanys()管道(
地图((数据:any[])=>{
如果(data&&data.length>0)返回此.router.createUrlTree(['/dashboard']);
否则返回这个.router.createUrlTree(['/companysignup']);
})
);
}

CanLoad guard的方法类型签名允许您返回一个
可观察的
、一个
承诺
,或者只是一个普通的
布尔值

CanActivate guard与之类似,只是您可以返回
布尔值
UrlTree
,但仍然允许它是可观察的或承诺的。这意味着该函数可以等待您的调用完成

出于您的目的,CanActivate就足够了,除非您想阻止客户端完全加载不同的路由模块,但这超出了本答案的范围

您的dataService请求返回一个可观察的数据,因此您需要做的就是将请求返回的数据映射到CanActivate的正确返回类型

以下是一种方法:

import { Injectable } from '@angular/core';
import { CanActivate, Router, CanLoad } from '@angular/router';
import { map } from 'rxjs/operators';
import { AuthService } from 'src/app/auth.service';
import { User } from 'src/models/user';
import { ListdataService } from 'src/app/listdata.service';

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

  constructor(private authService: AuthService, private router: Router,private dataService:ListdataService) { }

  canActivate() {
    return this.dataService.sendGetRequestcompanies().pipe(
      map((data: any[]) => {
        if(data && data.length > 0) return this.router.createUrlTree(['/dashboard']);
        else return this.router.createUrlTree(['/companysignup']);
      })
    );
  }

}
使用Typescript的一个主要优点是知道参数的类型或返回类型。如果不正确声明它们,则无法将您从自己手中解救出来,并且您错过了可以返回的不同选项

全类型方法将是:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean|UrlTree> | Promise<boolean|UrlTree> | boolean|UrlTree {
    return this.dataService.sendGetRequestcompanies().pipe(
      map((data: any[]) => {
        if(data && data.length > 0) return this.router.createUrlTree(['/dashboard']);
        else return this.router.createUrlTree(['/companysignup']);
      })
    );
  }
canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察的|承诺|布尔| UrlTree{
返回此.dataService.sendGetRequestCompanys()管道(
地图((数据:any[])=>{
如果(data&&data.length>0)返回此.router.createUrlTree(['/dashboard']);
否则返回这个.router.createUrlTree(['/companysignup']);
})
);
}

我在控制台中返回的是在运行后()一个包含一项的数组。然后,当我返回Console.log(this.companieslist)时,我返回一个空的数组,因为canLoad中的Console.log(this.companieslist)在可观察到的发出值和填充数组之前进行计算。js是异步的。我在控制台中返回的是在运行后()返回的一个包含一个项的数组。然后当我使用console.log(this.c