我有一个 component.ts 文件:
import { Component } from "@angular/core";
import {
FormBuilder,
FormControl,
FormGroup,
Validators,
} from "@angular/forms";
import { FaIconLibrary } from "@fortawesome/angular-fontawesome";
import { fas } from "@fortawesome/free-solid-svg-icons";
@Component({
selector: "app-course-form",
templateUrl: "./course-form.component.html",
styleUrls: ["./course-form.component.scss"],
})
export class CourseFormComponent {
constructor(
public fb: FormBuilder,
public library: FaIconLibrary
) {
library.addIconPacks(fas);
}
profileForm = this.fb.group({
title: ["", [Validators.required, Validators.minLength(2)]],
description: ["", [Validators.required, Validators.minLength(10)]],
author: ["", [Validators.required, Validators.pattern(/^[a-zA-Z0-9 ]+$/)]],
duration: [0, [Validators.required, Validators.min(1)]],
});
courseForm!: FormGroup;
title = new FormControl("");
description = new FormControl("");
author = new FormControl("");
duration = new FormControl(0);
authors: any[] = [];
durationText: string = "";
submitted = false;
removeAuthor(author: string) {
this.authors = this.authors.filter((a) => a !== author);
}
getDurationFormatted(minutes: number): string {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
return `${hours.toString().padStart(2, "0")}:${mins
.toString()
.padStart(2, "0")}`;
}
}
和 html 组件:
<h2>Create / Edit Course</h2>
<form [formGroup]="profileForm">
<div class="app-plate">
<div class="course">
<h3>Main Info</h3>
<div class="form__control">
<label for="title">Title</label>
<input type="text" id="title" placeholder="Input text" />
<span
*ngIf="profileForm.invalid"
id="titleErrorMessage"
class="text-danger"
>Title is required.</span
>
</div>
<div class="form__control">
<label for="description">Description</label>
<textarea
id="description"
placeholder="Input text"
rows="4"
cols="5"
></textarea>
<span
*ngIf="profileForm.invalid && profileForm.value.description"
id="descriptionErrorMessage"
class="text-danger"
>Description is required.</span
>
</div>
<div class="separator"></div>
<h3>Authors</h3>
<div class="form__control">
<div class="course__flex">
<input type="text" id="author" placeholder="Input Author Name" />
<app-button
id="createAuthor"
button_text="Create author"
></app-button>
</div>
<span *ngIf="" id="authorErrorMessage"
>New author should contain only latin letters and numbers.</span
>
<div class="course__authors">
<ul class="authors-list">
<li
*ngFor="let author of authors; track: author"
class="authors-list-item"
>
Id: {{ author.id }}. Name: {{ author.name }}
<app-button button_text="Remove" (click)="removeAuthor(author)">
</app-button>
</li>
</ul>
</div>
</div>
<div class="separator"></div>
<h3>Duration</h3>
<div class="form__control">
<div class="course__flex">
<input
type="number"
id="duration"
placeholder="Input duration"
formControlName="duration"
/>
<div class="course__duration">
<strong> </strong>
hours
</div>
</div>
<span *ngIf="" id="durationErrorMessage" class="text-danger"
>Duration is required and must be greater than 0.</span
>
</div>
<div class="form__action"></div>
</div>
</div>
</form>
<div class="buttons-container">
<app-button button_text="Cancel"></app-button>
<app-button button_text="Create course"></app-button>
</div>
我想展示:
<span
*ngIf="profileForm.invalid "
id="titleErrorMessage"
class="text-danger"
>Title is required.</span
>
仅当输入字段被触摸且仍然无效时。现在错误显示在加载的新表单上。怎么办?
我尝试使用表单控件,例如:
<div class="form__control">
<label for="title">Title</label>
<input
type="text"
id="title"
placeholder="Input text"
[formControl]="title"
/>
<span
*ngIf="profileForm.invalid && profileForm.controls['title'].touched"
id="titleErrorMessage"
class="text-danger"
>Title is required.</span
>
</div>
但是没有成功。
title
控件的验证不正确,因为您应该验证特定控件,而不是整个表单,如下所示:
<span
*ngIf="profileForm.controls.get('title').invalid && profileForm.controls.get('title').touched"
id="titleErrorMessage"
class="text-danger"
>Title is required.</span>
如果您使用 Angular 版本 14 或更高版本,您可以为表单提供强类型输入,这是一件好事。
<form [formGroup]="form">
<label for="name">Enter name</label>
<input type="text" id="name" formControlName="name" />
@if(form.controls.name.invalid && form.controls.name.touched) {
<span style="color: red">Name is required or invalid</span>
}
</form>
组件.ts
interface MyForm {
name: FormControl<string | null>;
}
@Component({...})
export class MyComponent implements OnInit {
private _fb = inject(FormBuilder);
protected form!: FormGroup<MyForm>; //form of type MyForm
ngOnInit(): void {
this.form = this._fb.group<MyForm>({
name: new FormControl(null, Validators.required),
});
}
}
观看演示