Angular 5 - 将数据从URL加载到提供程序中,以便在应用程序的任何位置都可用

问题描述 投票:1回答:4

我有一个编码的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());
    }
}
angular angular5 angular2-routing angular-providers
4个回答
0
投票

将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();

1
投票

你可以简单地去

@Injectable({
    providedIn: 'root'
})

让您的提供商随处可用。


1
投票

我想很多人告诉你要向NgModule声明它,但是你会遇到另一个问题,你不能从订阅中返回一个值。

所以你可以在这里阅读有关如何处理https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/的内容


1
投票

您可以通过将其添加到提供者数组,在提供者下的AppModules中注册它。然后通过路由保护访问它,您可以将引用传递给实现保护的类的构造函数

在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"]);
        }

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.