Angular如何将标签输入数组提交至Form表单并解决值为空问题
问题修复方案
核心错误原因
- 表单指令误用、变量名拼写不统一:根表单绑定应该用
[formGroup]而非formGroupName,且TS中定义的表单变量名和HTML、提交方法中引用的变量名大小写不一致 - 输入框错误绑定了
Keywords表单控件:该控件的定位是存储整个标签数组,却被绑定到了单个文本输入框,输入框的空值直接覆盖了控件原有值 - 修改
pills数组后没有同步更新Keywords控件的值:尤其是删除标签时返回了新数组引用,和控件初始持有的引用完全脱节 - 响应式表单与
ngModel混用引发状态冲突(此处ngModel仅用来存临时输入值,保留的话需要移除和表单控件的绑定关系)
修复步骤
第一步:修正HTML代码
<form [formGroup]="form" (ngSubmit)="submitValue()"> <div *ngFor="let pill of pills" class="pill">{{pill}} <span (click)="removePill(pill)"><i class="fa fa-times"></i></span></div> <!-- 移除input上的formControlName="Keywords"绑定,该输入框仅用来输入新标签,不需要绑定到存储数组的表单控件 --> <input class="keywordsInput" [(ngModel)]="value" (ngModelChange)="changeValue($event)" type="text"> <button type="submit" class="proceedBtn">Proceed to Submission</button> </form>
第二步:修正TypeScript代码
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Component, HostListener, OnInit } from '@angular/core'; pills : any[]=[]; value!:string; list: string[] = []; filteredList!: string[]; form!: FormGroup; // 变量名改为小写,和HTML、提交方法中的引用保持一致 FormUpload() { this.form = this.formBuilder.group({ // 其他表单控件逻辑保留 Keywords: [this.pills, [Validators.required]], // 修正语法错误,移除多余逗号 // 其他表单控件逻辑保留 }) } constructor(private formBuilder: FormBuilder) { } ngOnInit(): void { this.FormUpload(); } submitValue() { console.log(this.form.value); // 变量名和定义保持一致 } @HostListener('keyup', ['$event']) keyUp = (e: any) => { if (e.key === 'Enter') { e.preventDefault(); // 新增:阻止回车默认触发的表单提交行为 this.addPill(e.target.value); this.value = '' } } removePill(value: string) { this.pills = this.pills.filter(x => x !== value); // 新增:修改pills后同步更新表单控件的值 this.form.get('Keywords')?.setValue(this.pills); } addPill(value: string) { // 新增trim校验,防止添加空标签 if (!this.pills.find(x => x === value) && value.trim()) { this.pills.push(value); // 新增:修改pills后同步更新表单控件的值 this.form.get('Keywords')?.setValue(this.pills); } } changeValue(val: string) { this.doSearch(val); this.value = val; } doSearch(term: string) { this.filteredList = term && term.length > 1 ? this.list.filter(x => x.includes(term)) : []; }
内容的提问来源于stack exchange,提问作者AKASH
相关产品推荐
相关产品推荐

