面试题答案
一键面试- 构建嵌套表单结构
- 在组件类中,使用
FormGroup
和FormArray
来构建嵌套表单。 - 例如,假设订单表单包含收货地址和商品列表:
import { Component } from '@angular/core'; import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms'; @Component({ selector: 'app - order - form', templateUrl: './order - form.component.html', styleUrls: ['./order - form.component.css'] }) export class OrderFormComponent { orderForm: FormGroup; constructor() { this.orderForm = new FormGroup({ shippingAddress: new FormGroup({ street: new FormControl('', Validators.required), city: new FormControl('', Validators.required), zipCode: new FormControl('', [Validators.required, Validators.pattern('^[0 - 9]{5}$')]) }), productList: new FormArray([]) }); } get productList() { return this.orderForm.get('productList') as FormArray; } addProduct() { const productForm = new FormGroup({ productName: new FormControl('', Validators.required), quantity: new FormControl(1, [Validators.required, Validators.min(1)]) }); this.productList.push(productForm); } }
- 在组件类中,使用
- 自定义验证器编写
- 自定义验证器是一个函数,返回
ValidationErrors | null
。 - 例如,自定义一个验证邮编格式的验证器:
import { AbstractControl, ValidationErrors } from '@angular/forms'; export function zipCodeValidator(control: AbstractControl): ValidationErrors | null { const zipCode = control.value; if (!zipCode) { return null; } const valid = /^[0 - 9]{5}$/.test(zipCode); return valid? null : { invalidZipCode: true }; }
- 使用自定义验证器:
zipCode: new FormControl('', [Validators.required, zipCodeValidator])
- 自定义验证器是一个函数,返回
- 提交表单时统一处理验证结果
- 在模板中,绑定
(ngSubmit)
事件到组件类中的提交方法。 - 在提交方法中,检查
orderForm.valid
。如果表单有效,处理表单数据;如果无效,可遍历表单控件获取错误信息。
<form [formGroup]="orderForm" (ngSubmit)="onSubmit()"> <!-- 收货地址部分 --> <div formGroupName="shippingAddress"> <label for="street">Street:</label> <input type="text" id="street" formControlName="street"> <label for="city">City:</label> <input type="text" id="city" formControlName="city"> <label for="zipCode">Zip Code:</label> <input type="text" id="zipCode" formControlName="zipCode"> <div *ngIf="orderForm.get('shippingAddress.zipCode').hasError('invalidZipCode') && (orderForm.get('shippingAddress.zipCode').touched || orderForm.get('shippingAddress.zipCode').dirty)"> Invalid zip code format. </div> </div> <!-- 商品列表部分 --> <div formArrayName="productList"> <div *ngFor="let product of productList.controls; let i = index" [formGroupName]="i"> <label for="productName{{i}}">Product Name:</label> <input type="text" [id]="'productName' + i" formControlName="productName"> <label for="quantity{{i}}">Quantity:</label> <input type="number" [id]="'quantity' + i" formControlName="quantity"> </div> <button type="button" (click)="addProduct()">Add Product</button> </div> <button type="submit">Submit</button> </form>
onSubmit() { if (this.orderForm.valid) { const formData = this.orderForm.value; // 处理表单数据,如发送到服务器 console.log('Form submitted successfully:', formData); } else { // 遍历表单获取错误信息 Object.keys(this.orderForm.controls).forEach(field => { const control = this.orderForm.get(field); if (control instanceof FormGroup) { Object.keys(control.controls).forEach(subField => { const subControl = control.get(subField); if (subControl && subControl.errors) { console.log(`${field}.${subField} has errors:`, subControl.errors); } }); } else if (control instanceof FormArray) { control.controls.forEach((formGroup, index) => { Object.keys(formGroup.controls).forEach(subField => { const subControl = formGroup.get(subField); if (subControl && subControl.errors) { console.log(`productList[${index}].${subField} has errors:`, subControl.errors); } }); }); } else if (control && control.errors) { console.log(`${field} has errors:`, control.errors); } }); } }
- 在模板中,绑定