Angular 5 - 将数据从 URL 加载到提供程序中,以便在应用程序中随处可用

Angular 5 - Loading data from URL into a provider so it's available everywhere in the app

我有一个编码的 URL 参数,我需要在应用程序初始化时对其进行解码。我需要在提供者中执行此操作,因为该对象需要对路由守卫和组件可用。

我有以下供应商。它获取传入的查询参数并将其解析为接口。

import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { MyObject } from './data.d';

@Injectable()
export class DataProvider {

    constructor(private route: ActivatedRoute) { }

    public get() {
      debugger;
      this.route.queryParams.subscribe(params => {
        let payload = params['data'] !== undefined ? Base64.decode(params['data']) : null;
        return payload ? <MyObject>JSON.parse(payload) : null;
      });
    }
}

关于如何将其添加到我的提供程序数组以及如何从应用程序中的其他位置(特别是路由守卫)访问它的语法,我遇到了问题。正确的设置方法是什么?

编辑:似乎查询参数在提供程序初始化时可能不可用。我在哪里可以在组件以外的地方解析查询参数?我需要能够在路由守卫中访问它。

app.guard.ts:

import { Injectable } from '@angular/core';
import { Router, RouterStateSnapshot, ActivatedRouteSnapshot, CanActivate } from '@angular/router';
import { SessionService } from './services/session.service';
import { DataProvider } from './data.provider';

@Injectable()
export class SessionIsValidGuard implements CanActivate {

    constructor(
        private router: Router, private sessionService: SessionService, private dataProvider: DataProvider
    ) {}

    /*
    * Main guard to verify that session ID is valid before proceeding
    */
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
      // When the below is called, dataProvider.get() returns null
      let params = this.dataProvider.get();
      if (this.sessionService.isValidSessionId(params.transactionId)) {
        return true;
      } else {
        this.router.navigate(['/error', { error: 'Invalid session' }]);
      }
    }
}

app.component.ts:

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { DataProvider } from './data.provider';

/*
* Main app component that houses all views.
*/
@Component({
    selector: 'app-comp',
    templateUrl: './app.component.html'
})

export class AppComponent implements OnInit {

    constructor(private router: Router, private route: ActivatedRoute, private srcService: SRCService, private dataProvider: DataProvider) {}

    ngOnInit() {
      // Here dataProvider.get() returns the expected value
      console.log(this.dataProvider.get());
    }
}

你可以直接使用

@Injectable({
    providedIn: 'root'
})

让您的提供商随处可用。

将 DataProvider 服务导入 app.module.ts 文件

@NgModule({
   providers: [DataProvider]
})

然后你可以从其他组件访问它

constructor(private dataProvider: DataProvider)

this.dataProvider.get();

编辑:只在路由守卫中解码 URL 一次,然后在组件中也使用它。

将查询参数访问到路由保护文件中:

export class RouteGuard implements CanActivate {
   public params: any;
   canActivate(
     route: ActivatedRouteSnapshot,
     state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | 
     boolean {
        this.params = route.queryParams;
        if (this.sessionService.isValidSessionId(params.transactionId)) {
           return true;
        } else {
           this.router.navigate(['/error', { error: 'Invalid session' }]);
        }
     }

     get() {
         let payload = this.params['data'] !== undefined ? 
         Base64.decode(this.params['data']) : null;
         return payload ? <MyObject>JSON.parse(payload) : null;
       });
     }
}

使用这种解码方式进入组件

constructor(private routeGaurd: RouteGaurd)

this.routeGaurd.get();

我想很多人都告诉过你关于将它声明到 NgModule 的事情,但是你会遇到另一个问题,你不能 return 来自订阅的值。

因此您可以在此处阅读有关如何处理该问题的信息https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

您可以通过将其添加到提供者 array.After 来在提供者下的 AppModules 中注册它,要通过路由保护访问它,您可以将引用传递给实现的 class 的构造函数守卫

在 AppModules.ts 中看起来像这样

@NgModule({
  imports: [
    CommonModule,

  ],
  exports: [],
  declarations: [],
  providers: [

    AdminAuthGaurd,

  ]

})

RoutGaurd.ts 应该是这样的

export class AdminAuthGaurd implements CanActivate {
    constructor(private authService: AuthenticationService, private router: Router) { }
    canActivate(): boolean {
        if(this.authService.getUserpermissions()==="Admin"){
                return true;
        }
        else{
            this.router.navigate(["/login"]);
        }

    }
}