angular 更改输入元素的有效条件

angular change an input element's valid condition

我有一个包含表单的 angular 应用程序。我有一个输入字段,用户可以在其中输入一个字符串并单击一个添加按钮,然后它会解析输入、验证它并将其添加到表单的模型中。输入元素的 [(ngModel)] 绑定到组件上的 瞬态变量 属性。验证成功后,瞬态变量的值将被清除,以便用户可以输入另一个要添加到模型中的项目。

瞬态变量是必填字段的输入字段,因为如果您从未向模型添加新项目,则无法提交表单。

I want to change the valid condition of the input element so that when at least one new item was added to the model, the input element field can be left blank and I can successfully submit the form.

form.component.ts:

import { Component, OnInit } from '@angular/core';
import { Model } from './model';

@Component({
  selector: 'app-form',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
  model: Model;
  transientItem: string;

  constructor() { }

  get diagnostic() { return JSON.stringify(this.model); }

  ngOnInit() {
    this.model = new Model([]);
  }

  onSubmit() {
    //handle submit logic
  }

  addItem() {
    const items = this.transientItem.split(' ');
    if (items.length === 3) {
      const newItem = {
        itemName: items[0],
        itemValue: items[1],
        itemLabel: items[2]
      };
      this.model.items.push(newItem);
      this.transientItem = '';
    } else {
      alert('invalid item format');
    }
  }

}

form.component.html:

<form (ngSubmit)="onSubmit()" #myForm="ngForm">
  {{diagnostic}}
  <div class="form-group">
    <input type="text" class="form-control" required [(ngModel)]="transientItem" name="item" #item="ngModel" />
    <button type="button" (click)="addItem()">Add</button>
  </div>
  <button type="submit" [disabled]="!myForm.form.valid">Submit</button>
</form>

model.ts:

export class Model {
    constructor(
        public items: {
            itemName: string,
            itemValue: string,
            itemLabel: string
        }[]
    ) { }
}

当前行为:如果输入的值为空,提交按钮将被禁用,但只要我在文本字段中输入内容,我就可以提交表单...

预期行为:只有当我的模型在其项目 属性 中至少有 1 项时,我才能提交表单。如果我在模型中有 1 个项目,并且我将输入字段留空,我仍然可以提交表单,因为已经添加了一个项目。

我几乎总是使用 ReactiveForms,因为 API 提供了许多有用的工具来构建从简单到复杂的表单。在您的情况下,解决方案可能类似于:

import { Component } from '@angular/core';
import { FormControl, FormGroup, FormArray, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  template: `
    <form [formGroup]="form">
      <input formControlName="newItem">
      <button type="button" (click)="addItem()" [disabled]="!item.valid">ADD</button>
      <hr>
      <button type="button" (click)="submit()" [disabled]="!items.valid">SUBMIT</button>
      <hr>
      <ul>
        <li *ngFor="let item of items.controls; let i = index">{{ item.value }} - <button type="button" (click)="removeItem(i)">DELETE</button></li>
      </ul>
    </form>
  `
})
export class AppComponent  {
  form: FormGroup;

  get item() {
    return this.form.get('newItem') as FormControl;
  }

  get items() {
    return this.form.get('items') as FormArray;
  }

  constructor() {
    this.form = new FormGroup({
      newItem: new FormControl('', Validators.required),
      items: new FormArray([], Validators.required),
    })
  }

  addItem() {
    this.items.push(new FormControl(this.item.value));
    this.item.reset('');
  }

  removeItem(i: number) {
    this.items.removeAt(i);
  }

  submit() {
    console.log(this.form.value);
  }
}

让我们稍微解释一下我们在做什么。

我们正在创建一个新的 FormControl,启用 ADD 按钮应该需要它。

newItem: new FormControl('', Validators.required)

在我们的 HTML

<button type="button" (click)="addItem()" [disabled]="!item.valid">ADD</button>

我们还在创建一个新的 FormArray 来存储我们想要保留的所有新项目,同时我们正在使用必需的验证器来使用我们的 SUBMIT 按钮的状态

items: new FormArray([], Validators.required)

进出HTML

<button type="button" (click)="submit()" [disabled]="!items.valid">SUBMIT</button>

是的,我们的整个表格不会 VALID 但我们不在乎。当您点击 SUBMIT 按钮时,我们使用 this.form.value['items'] 提取项目,这将是我们添加的项目数组。

这里还有一个stackblitz.