Angular 16中NgZorro Modal传数据报错:TypeError读取name属性失败
问题描述
使用Ant Design for Angular的ng-zorro-antd库,原Angular 12环境下功能正常,升级到Angular 16后出现以下错误:
ERROR TypeError: Cannot read properties of undefined (reading 'name')
该错误反复出现甚至导致浏览器崩溃。
Modal创建代码:
private _createDeleteModal(vehicleGroupDetails: VehicleGroupDetails) { this.modalService .create({ nzTitle: 'Delete Vehicle Group', nzContent: VehicleGroupDeleteComponent, nzComponentParams: { existingVehicleGroup: vehicleGroupDetails }, }) }
接收参数的Modal组件代码:
export class VehicleGroupDeleteComponent implements OnInit { @Input() existingVehicleGroup: VehicleGroupDetails; ... this.vehicleGroupForm = new FormGroup({ name: new FormControl(this.existingVehicleGroup?.name ?? '', [ Validators.required,... ]) }) }
目前无法通过@Input获取到传入的参数数据。
解决方案
1. 匹配ng-zorro-antd与Angular版本
Angular 16需要搭配^16.x.x版本的ng-zorro-antd,执行以下命令升级到兼容版本:
ng update ng-zorro-antd
2. 改用NzModalRef传递参数(官方推荐)
新版ng-zorro对Modal传参方式做了优化,推荐通过NzModalRef直接操作组件实例传递参数:
发送参数端修改:
private _createDeleteModal(vehicleGroupDetails: VehicleGroupDetails) { const modalRef = this.modalService.create({ nzTitle: 'Delete Vehicle Group', nzContent: VehicleGroupDeleteComponent, }); // 直接给组件实例赋值参数 modalRef.instance.existingVehicleGroup = vehicleGroupDetails; }
接收参数端(两种方式二选一):
方式一:保留@Input
export class VehicleGroupDeleteComponent implements OnInit { @Input() existingVehicleGroup: VehicleGroupDetails; vehicleGroupForm: FormGroup; ngOnInit(): void { this.initForm(); } private initForm(): void { this.vehicleGroupForm = new FormGroup({ name: new FormControl(this.existingVehicleGroup?.name ?? '', [ Validators.required,... ]) }); } }
方式二:通过NzModalRef注入获取
import { NzModalRef } from 'ng-zorro-antd/modal'; export class VehicleGroupDeleteComponent implements OnInit { existingVehicleGroup: VehicleGroupDetails; vehicleGroupForm: FormGroup; constructor(private modalRef: NzModalRef) {} ngOnInit(): void { // 从Modal配置中读取参数 this.existingVehicleGroup = this.modalRef.getConfig().nzComponentParams?.existingVehicleGroup; this.initForm(); } private initForm(): void { this.vehicleGroupForm = new FormGroup({ name: new FormControl(this.existingVehicleGroup?.name ?? '', [ Validators.required,... ]) }); } }
3. 确保输入属性初始化时机
Angular 16对输入属性的访问时机更严格,避免在构造函数中访问@Input,改用ngOnInit或ngOnChanges处理:
import { SimpleChanges, OnChanges } from '@angular/core'; export class VehicleGroupDeleteComponent implements OnInit, OnChanges { @Input() existingVehicleGroup: VehicleGroupDetails; vehicleGroupForm: FormGroup; ngOnInit(): void { this.initForm(); } ngOnChanges(changes: SimpleChanges): void { // 当输入参数变化时重新初始化表单 if (changes['existingVehicleGroup']) { this.initForm(); } } private initForm(): void { this.vehicleGroupForm = new FormGroup({ name: new FormControl(this.existingVehicleGroup?.name ?? '', [ Validators.required,... ]) }); } }
4. 启用编译时检查
在tsconfig.json中开启strictInputAccessTypes,提前发现输入属性未初始化的问题:
{ "compilerOptions": { "strictInputAccessTypes": true } }
内容的提问来源于stack exchange,提问作者Tony Brasunas
相关产品推荐
相关产品推荐

