在Angular的整个组件中共享服务

时间:2019-05-02 07:35:31

标签: angular

我是Angular的新手,正在使用angular7。我在共享服务userEmail中有一个变量pagedoctorService,其默认值为“ unknown”。成功登录后,变量将使用登录的电子邮件进行更新。我已将此服务导入其他组件,但是当从其他组件访问userEmail时,它会显示默认值(未知)。

这是我所做的:

app.module.ts

...
import { PagedoctorService } from './services/pagedoctor.service';
...
...
providers: [PagedoctorService],
...

pagedoctor.service.ts

import { Injectable } from '@angular/core';
import { OktaAuthService } from '@okta/okta-angular';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PagedoctorService {

  private accessToken;
  private headers;

  public userFullname: string= 'unknown';
  public userEmail: string= 'unknown';

  constructor(private oktaAuth: OktaAuthService, private http: HttpClient) {
    this.init();
  }

  async init() {
    this.accessToken = await this.oktaAuth.getAccessToken();
    this.headers = new HttpHeaders({
      Authorization: 'Bearer ' + this.accessToken
    });
  }
...

login.component.ts

import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart} from '@angular/router';
import { PagedoctorService } from '../../services/pagedoctor.service';
...
constructor(private pdService: PagedoctorService){}
ngOnInit() {
...
//After successful login attempt using Okta
this.pdService.userEmail = res.user.profile.login; 
console.log(this.pdService.userEmail); //This shows that email is set correctly
this.signIn.loginRedirect('/urlform');
}

urlform.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { PagedoctorService } from '../../services/pagedoctor.service';
...
...
constructor(private pdService: PagedoctorService) {
console.log(this.pdService.userEmail); // <== This shows *unknown*

听起来像是我在模块级别提供服务时使用的是新版本的服务。 我不确定我在这里想念的是什么。预先感谢您的合作。

3 个答案:

答案 0 :(得分:1)

在根注入器中提供服务实例的最佳方法是整个应用程序:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class PagedoctorService {
}

请参阅:https://angular.io/guide/providers

此处的示例:https://stackblitz.com/edit/angular-fumwxh

重要

尝试使您的构造函数更干净。不做任何动作。不要在构造函数中调用任何方法。您能否从构造函数的外部而不是内部调用init方法。也许异步方法“ init”是问题所在。

但是您的代码也应该工作。也许您可以提供您的PagedoctorService的代码。

  

更新   重定向。好了,解决了这个问题!   在您的login.component中,您调用:this.signIn.loginRedirect('/ urlform')。

当您重定向SPA时,将重新加载SPA,并从头开始创建整个注射器。这意味着您所有的状态都将丢失。您可以使用本地存储或会话存储来避免这种情况!

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class PagedoctorService {
...
public get userFullname(): string {
    const res = localStorage.getItem('userFullname');
    return res == undefined ? 'unknown' : res;
  }
  public set userFullname(value: string) {
    localStorage.setItem('userFullname', value);
  }
}
...

答案 1 :(得分:1)

在将公共财产投入服务时,我会很小心。我通常在服务中添加的唯一公共属性是管理状态的主题。如果您想将userEmail传递给其他组件,建议您将其设置在本地存储中,并在更改时将其设置为主题,或者将其作为父项或子项的输入。对于路由,还可以通过路由配置将数据从登录组件传递到导航的路由。请参见下面的链接:

How do I pass data to Angular routed components?

我希望这会有所帮助。

答案 2 :(得分:0)

login.component

中尝试
this.pdService.changeEmail(res.user.profile.login);

PagedoctorService

` private emailOriginale = new BehaviorSubject('unknown');
     emailActtual = this.emailOriginale .asObservable(); 
     changeEmail(email: string) {
         this.emailOriginale.next(email)
     }`

urlform.component.ts结尾

  this.pdService.emailActtual.subscribe(res => console.log(res));