Angular 5服务变量未定义

Posted

技术标签:

【中文标题】Angular 5服务变量未定义【英文标题】:Angular 5 service variable undefined 【发布时间】:2018-11-16 02:08:23 【问题描述】:

使用 Angular 5,我有 2 个组件和一个共享服务,我想将数据从一个组件传递到另一个组件。

我在接收组件的 oninit 中订阅了变量并尝试 console.log 结果,但它始终显示为 undefined

通过html按钮点击selectPlan()调用初始服务函数调用_quoteSummaryService.setSelectedPlan()的组件,传入的对象不是显示为undefined

我什至可以 console.log 服务函数中的对象,它也不是undefined。订阅后,在接收组件 oninit 函数上调用 console.log 时只有undefined

变量selectedPlan 在插入到接收组件HTML 中时显示为undefined selectedPlan?

quote-summary.service.ts

import  Injectable  from '@angular/core';
import  Subject     from 'rxjs/Subject';
import  Quote  from '../models/quote-response.model';

@Injectable()
export class QuoteSummaryService 

    constructor()

    private _quoteSelectedPlanSource = new Subject<Quote>();
    public quoteSelectedPlan = this._quoteSelectedPlanSource.asObservable();

    setSelectedPlan(selectedPlan:Quote) 
        this._quoteSelectedPlanSource.next(selectedPlan);
    

quote-select-plan.component.ts:(进行服务调用的组件)

export class QuoteSelectPlanComponent implements OnInit 
  constructor(private _quoteSummaryService:QuoteSummaryService, private _router: Router) 

  selectPlan(selectedPlan) 
    this._quoteSummaryService.setSelectedPlan(selectedPlan);
    if (selectedPlan !== undefined) 
      this._router.navigateByUrl('/quote/details/assumptions');
    
  

quote-summary.component.ts:(订阅变量但显示为未定义的组件)

export class QuoteSummaryComponent implements OnInit 
  constructor(private _quoteSummaryService:QuoteSummaryService)  

  public selectedPlan: Quote;

  ngOnInit() 
    this._quoteSummaryService.quoteSelectedPlan.subscribe(plan =>  this.selectedPlan = plan );
    console.log(this.selectedPlan) //showing as undefined
  

我现在有点难过。这是我尝试过但没有奏效的事情的清单。我觉得我错过了一些简单的东西。

将服务中的变量源从Subject类型更改为BehaviorSubject

将 Getter 添加到接收组件并尝试直接从服务访问变量。

HTML 中的异步管道

基本上this question答案中提到的所有内容

尝试订阅发送组件中的变量,看看是否有任何作用

【问题讨论】:

Injectable 装饰器不应该是这样的:@Injectable() ?? @AshishRanjan 是的,对不起,我现在会更新 @AshishRanjan 仍然显示undefined console.log(this.selectedPlan);下subscription RxJS 是异步的,因此您的分配可能发生在 console.log 之后 【参考方案1】:

javascript 和它一起 TypeScript 是一种异步语言。当您订阅某些内容时,当前的函数流程会继续,并且订阅的函数只会在可观察对象发出后被调用。这是在console.log 之后。

把你的代码改成这样,你就会得到你所期望的:

ngOnInit() 
  this._quoteSummaryService.quoteSelectedPlan.subscribe(plan =>  
    this.selectedPlan = plan;
    console.log(this.selectedPlan);
  );

您可以在订阅之前和之后添加额外的console.log,您会看到在调用订阅函数之前记录了这些内容。

即使Observable 可以同步,但最好永远不要相信它。

【讨论】:

但为什么它不会出现在我的 HTML 中并抱怨它未定义?? @blueprintChris 因为在第一次呈现 HTML 时它是未定义的。这也发生在订阅的函数被调用之前。为了防止可能未定义的对象出现任何错误,您必须在模板中使用安全导航运算符.? @blueprintChris 如果您还在ngAfterViewInit 钩子中放置console.log,您可以看到这一点。您会看到它在记录this.selectedPlan 之前也被调用。这意味着在初始渲染时,selectedPlan 仍然未定义 @blueprintChris 修复什么 :)?我没有看到错误消息或任何内容。只是一个 console.log 在错误的地方 它在 HTML 中显示未定义。无法访问 HTML 中的变量。

以上是关于Angular 5服务变量未定义的主要内容,如果未能解决你的问题,请参考以下文章

WebStorm,Angular 4中未解决的变量

为什么我的角度服务变量未定义?

手动传递的 Angular 路由变量在组件中未定义

错误:使用 Sass 的 Angular 组件中的未定义变量

Observable 的异步行为导致变量未定义

在外部 JavaScript 库中定义函数时如何检查未定义? (Angular4/5)