如何创建包含对象类型输入字段的Angular表单
报错核心原因
- 你定义的
Hotels类中bookingList是Contract数组类型,直接用hotel.bookingList.start_date访问属性的写法错误,数组需要指定下标才能访问对应位置的Contract实例属性 - 初始化
hotel实例时没有给bookingList赋值,默认值为undefined,访问undefined的属性必然抛出错误 - 表单中多个输入框的
name属性重复,[(ngModel)]双向绑定依赖唯一的name属性区分表单项,重复会导致绑定异常 - 日期输入框的占位符、类型存在笔误,和业务逻辑不匹配
修改步骤
1. 组件侧初始化嵌套属性
首先在组件中导入Contract类,然后在ngOnInit生命周期中初始化bookingList数组:
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { Hotels } from 'src/app/models/hotels'; import { Contract } from 'src/app/models/contract'; // 新增导入Contract类 import { HotelsService } from 'src/app/services/hotels.service'; @Component({ selector: 'app-add-hotels', templateUrl: './add-hotels.component.html', styleUrls: ['./add-hotels.component.css'] }) export class AddHotelsComponent implements OnInit { hotel : Hotels = new Hotels(); constructor(private _hotelService : HotelsService, private _router:Router) { } ngOnInit(): void { // 初始化bookingList数组,默认提供1条空合同数据用于录入 this.hotel.bookingList = [new Contract()]; } saveHotel(){ this._hotelService.saveHotels(this.hotel).subscribe( data =>{ console.log('response', data) this._router.navigateByUrl("/hotels"); } ) } }
同时请确认你当前组件所属的模块中已经导入了FormsModule,否则[(ngModel)]无法正常使用,需要在模块的imports数组中添加:
import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ // 其他导入项 FormsModule ] })
2. 模板表单代码修正
修改绑定路径、name属性和占位符:
<form (ngSubmit)="saveHotel()"> <input type="text" name="name" [(ngModel)]="hotel.name" placeholder="请输入酒店名称"/> <input type="email" name="email" [(ngModel)]="hotel.email" placeholder="请输入酒店邮箱"/> <input type="text" name="address1" [(ngModel)]="hotel.address1" placeholder="请输入酒店地址第一行"/> <input type="text" name="address2" [(ngModel)]="hotel.address2" placeholder="请输入酒店地址第二行"/> <!-- 绑定数组第0项的属性,name属性保持唯一,修正占位符 --> <input type="text" name="start_date" [(ngModel)]="hotel.bookingList[0].start_date" placeholder="请输入合同开始日期"/> <input type="text" name="end_date" [(ngModel)]="hotel.bookingList[0].end_date" placeholder="请输入合同结束日期"/> <button type="submit">新增酒店</button> </form>
进阶:支持多合同动态录入
如果需要同时录入多份合同,可以扩展功能支持动态新增行:
- 组件中新增添加合同的方法:
addNewContract() { this.hotel.bookingList.push(new Contract()); }
- 模板中用
*ngFor遍历渲染合同输入框:
<div *ngFor="let contract of hotel.bookingList; let i = index"> <input type="text" [name]="'start_date_' + i" [(ngModel)]="contract.start_date" placeholder="请输入合同开始日期"/> <input type="text" [name]="'end_date_' + i" [(ngModel)]="contract.end_date" placeholder="请输入合同结束日期"/> </div> <button type="button" (click)="addNewContract()">新增合同</button>
内容的提问来源于stack exchange,提问作者Mystica
相关产品推荐
相关产品推荐

