【问题标题】:Angular 5 service variable undefinedAngular 5服务变量未定义
【发布时间】: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 之后

标签: angular service undefined


【解决方案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 中的变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 2018-09-10
  • 1970-01-01
  • 2018-06-26
相关资源
最近更新 更多