Angular 5 — загрузка данных из URL-адреса в провайдера, чтобы они были доступны везде в приложении.

У меня есть закодированный параметр 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());
    }
}

person Paul Erdos    schedule 12.03.2019    source источник


Ответы (4)


Импорт службы 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();
person Zarna Borda    schedule 12.03.2019
comment
Довольно просто получить к нему доступ из компонента, но как насчет модуля маршрутизации? Когда я пытаюсь получить доступ к dataProvider.get() из защиты маршрутизации, он равен нулю. - person Paul Erdos; 12.03.2019
comment
Обновлено. Основная проблема заключается в том, что параметры запроса недоступны при инициализации службы DataProvider. - person Paul Erdos; 12.03.2019
comment
Вы пытались получить доступ к параметру запроса URL в охрану маршрута? - person Zarna Borda; 12.03.2019
comment
Я могу получить доступ к параметрам запроса в защите маршрута, но тогда мне придется дважды декодировать параметр — один раз в защите маршрутизации и снова в компоненте. Я бы предпочел разобрать его один раз и использовать объект везде, где мне это нужно. - person Paul Erdos; 12.03.2019
comment
Ок. Затем декодируйте параметры в Guard, и вы можете использовать это в компоненте - person Zarna Borda; 12.03.2019
comment
Как передать значение от сторожа к компоненту? - person Paul Erdos; 12.03.2019

Вы можете просто пойти с

@Injectable({
    providedIn: 'root'
})

чтобы ваш провайдер был доступен везде.

person Kevin FONTAINE    schedule 12.03.2019
comment
Разве это не доступно только в Angular 6? Я использую Angular 5 и в данный момент не могу обновиться. - person Paul Erdos; 12.03.2019
comment
Кажется так. Поможет ли это: stackoverflow.com/questions/50489412/? - person Kevin FONTAINE; 12.03.2019

Я думаю, многие ребята говорят вам об объявлении его в NgModule, но у вас будет другая проблема, что вы не можете вернуть значение из подписки.

Итак, вы можете прочитать о том, как с этим справиться, здесь https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

person anthony willis muñoz    schedule 12.03.2019

Вы можете зарегистрировать его в 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"]);
        }

    }
}
person Sathiraumesh    schedule 12.03.2019
comment
Значение определено в компоненте, но не в функции защиты маршрутизации. - person Paul Erdos; 12.03.2019