Angular中已填充的Contract对象访问字段返回undefined问题求助
问题根因
this.contractService.getContract()是基于RxJS的异步请求,调用subscribe()后不会阻塞后续代码执行。你调用GetContract()后接口还没返回结果,就直接执行了后续访问this.contract的逻辑,此时this.contract还没被赋值,所以报undefined。你调试时能看到赋值是因为接口返回后才触发赋值操作,晚于你访问字段的时机。
修复方案
方案1:将依赖contract的逻辑移入异步回调
把后续取client的逻辑放到接口返回成功的回调中,保证访问this.contract时已经完成赋值,修改后代码如下:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Client } from '../../models/client'; import { Contract } from '../../models/Contract'; import { ClientService } from '../../services/client.service'; import { ContractService } from '../../services/contract.service'; @Component({ selector: 'app-contract-customer', templateUrl: './contract-customer.component.html', styleUrls: ['./contract-customer.component.css'] }) export class ContractCustomerComponent implements OnInit { public contractNumber: string; public client: Client; public contract: Contract; constructor(private route: ActivatedRoute, private clientService: ClientService, private contractService: ContractService) { } ngOnInit():void { // 更推荐用ActivatedRoute取路由参数,不需要手动拆分url // this.contractNumber = this.route.snapshot.paramMap.get('你定义的路由参数名'); const url = window.location.href; var parts = url.split('/', 6); this.contractNumber = parts[4]; console.log("Contract Id form url : " + this.contractNumber); this.GetContractClient(); } GetContract(id: string) { this.contractService.getContract(Number(id)).subscribe(result => { this.contract = result; // 接口返回后再执行依赖contract的逻辑 console.log("test id contract client" + this.contract.contractId); this.GetClient(); }, error => { console.log(error) }); } GetClient() { this.clientService.getClient(this.contract.contractId).subscribe(result => { this.client = result; }, error => { console.log('something wrong here!!!') console.log(error) }); } GetContractClient() { this.GetContract(this.contractNumber); } }
方案2:使用RxJS操作符链式调用
如果想让逻辑更清晰可维护,可以让GetContract返回Observable,用switchMap操作符串联两个请求:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { switchMap } from 'rxjs/operators'; import { Client } from '../../models/client'; import { Contract } from '../../models/Contract'; import { ClientService } from '../../services/client.service'; import { ContractService } from '../../services/contract.service'; @Component({ selector: 'app-contract-customer', templateUrl: './contract-customer.component.html', styleUrls: ['./contract-customer.component.css'] }) export class ContractCustomerComponent implements OnInit { public contractNumber: string; public client: Client; public contract: Contract; constructor(private route: ActivatedRoute, private clientService: ClientService, private contractService: ContractService) { } ngOnInit():void { const url = window.location.href; var parts = url.split('/', 6); this.contractNumber = parts[4]; console.log("Contract Id form url : " + this.contractNumber); this.GetContractClient(); } GetContract(id: string) { return this.contractService.getContract(Number(id)); } GetContractClient() { this.GetContract(this.contractNumber).pipe( switchMap(contract => { this.contract = contract; console.log("test id contract client" + this.contract.contractId); return this.clientService.getClient(contract.contractId); }) ).subscribe(result => { this.client = result; }, error => { console.log(error); }); } }
内容的提问来源于stack exchange,提问作者J.C
相关产品推荐
相关产品推荐

