by Gulfam Ansari
由Gulfam Ansari
AngularReact形式介绍 (An introduction to Angular Reactive Forms)
Angular uses two different approaches to handle forms. The first one is the Template Driven Approach and the other one is the Reactive Approach. Both approaches use different techniques to handle your form data. In the Template Driven Approach, we define the form structure in our HTML code. On the other hand, in the Reactive Approach, the structure of the form is defined in the component class.
Angular使用两种不同的方法来处理表单。 第一个是模板驱动方法,另一个是React方法。 两种方法都使用不同的技术来处理表单数据。 在“模板驱动方法”中,我们在HTML代码中定义表单结构。 另一方面,在响应式方法中,表单的结构在组件类中定义。
The Reactive Approach is more complex as compared to the Template Driven Approach, because it can provide lots of other functionalities. In this article, we will create a contact form using the Angular Reactive Approach. So what are we waiting for? Let’s dive deep into it.
与模板驱动方法相比,React式方法更为复杂,因为它可以提供许多其他功能。 在本文中,我们将使用Angular Reactive Approach创建联系表单。 那么,我们还等什么呢? 让我们深入了解它。
如何在Angular中使用React形式? (How To Use Reactive Forms In Angular?)
To implement Reactive Forms in Angular, we follow the below steps.
要在Angular中实现React式表单,请执行以下步骤。
Import the Reactive Form Module in the
app.module.ts
file.将React性表单模块导入
app.module.ts
文件中。Create an instance of
FormGroup
class in the component file and initialize the default values of allFormControls
.在组件文件中创建
FormGroup
类的实例,并初始化所有FormControls
的默认值。Bind the
FormGroup
andFormConrtol
in the HTML code.在HTML代码中绑定
FormGroup
和FormConrtol
。
1.导入ReactiveFormsModule (1. Importing The ReactiveFormsModule)
To use Reactive forms in your application you need to import ReactiveFormsModule
in your parent module.ts
file. This is just like how we import FormsModule
in ourapp.module.ts
file to use Template Driven forms.
要在应用程序中使用Reactive表单,您需要在父module.ts
文件中导入ReactiveFormsModule
。 就像我们在app.module.ts
文件中导入FormsModule
以使用“模板驱动”表单一样。
import { AppComponent } from './app.component';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
2.在组件中定义FormGroup (2. Define FormGroup In The Component)
As we know, in the Reactive Form Approach, the structure of the form is defined in the component file, and this structure is synced with HTML code using formGroup
directive. So to create our contact form, we first need to define our form model in the component class.
众所周知,在响应式表单方法中,表单的结构是在组件文件中定义的,并且该结构使用formGroup
指令与HTML代码同步。 因此,要创建联系表单,我们首先需要在组件类中定义表单模型。
Form Control is the smallest building block of a reactive form which keeps track of all HTML input value and their validations.
表单控件是React表单的最小构建块,可跟踪所有HTML输入值及其验证。
Form Group is a collection of FormControls which combines all the HTML input values into a single object.
窗体组是FormControls的集合,它将所有HTML输入值组合到一个对象中。
Now it’s time to create our contact form component file.
现在是时候创建我们的联系表单组件文件了。
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.scss']
})
export class ContactFormComponent implements OnInit {
public contactForm: FormGroup;
constructor() { }
ngOnInit() {
this.contactForm = new FormGroup({
'name': new FormControl(null),
'email': new FormControl(null),
'subject': new FormControl(null),
'message': new FormControl(null)
});
}
}
In the above code, we import FormGroup class from @angular/forms
and declare the FormGroup
property named as contactform
.
在上面的代码中,我们从@angular/forms
导入FormGroup类,并将FormGroup
属性声明为contactform
。
Define all the FormControl
and group them using FormGroup
and assign it to contactForm
.
定义所有FormControl
并使用FormGroup
对其进行FormGroup
并将其分配给contactForm
。
3.在HTML文件中绑定FormControls (3. Bind the FormControls in the HTML File)
Bind our FormGroup property in the Template using the formGroup
directive.
使用formGroup
指令将我们的FormGroup属性绑定到Template中。
Wire up all FormControls in the Template using formControlName
directive to map each input element of the HTML.
使用formControlName
指令连接模板中的所有FormControl,以映射HTML的每个输入元素。
We are also using ngSubmit
directive to post the form data by clicking on the submit button.
我们还使用ngSubmit
指令通过单击ngSubmit
来发布表单数据。
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
<input type="text" name="name" placeholder="Your name" formControlName="name">
<input type="text" name="email" placeholder="Your email" formControlName="email">
<input type="text" name="subject" placeholder="Subject" formControlName="subject">
<textarea name="message" placeholder="Your Message" formControlName="message"></textarea>
<button type="submit" class="btn btn-large">Send Message</button>
</form>
验证方式 (Validation)
You have implemented the basic version of a Reactive form. Now take a step upward and validate your input values before sending them to the database.
您已经实现了Reactive表单的基本版本。 现在,在将输入值发送到数据库之前,先向上一步并进行验证。
Actually, we do lots of validation in the backend layer before sending the data to the database, but to make our app faster we introduce some validation at the client side as well. Angular ReactiveForm module does this validation job very effectively. So let's validate our inputs before sending them to the database.
实际上,在将数据发送到数据库之前,我们在后端层进行了大量验证,但是为了使我们的应用程序更快,我们也在客户端引入了一些验证。 Angular ReactiveForm模块非常有效地完成了此验证工作。 因此,在将输入发送到数据库之前,请先对其进行验证。
To add validators in your form, we need to import Validators
class from @angular/form.
and add validators while creating new FormControl object.
要在您的表单中添加验证器,我们需要从@angular/form.
导入Validators
类@angular/form.
并在创建新的FormControl对象时添加验证器。
The FormControl class constructor takes 3 arguments.
FormControl类的构造函数带有3个参数。
- The default value of an input 输入的默认值
- Validator or Array of Validators 验证器或验证器数组
- Async Validators 异步验证器
For form validation, we are using the 2nd argument of the FormControl class constructor.
为了进行表单验证,我们使用FormControl类构造函数的第二个参数。
this.contactForm = new FormGroup({
'name': new FormControl(Enter Name, Validators.required),
'email': new FormControl(null, [Validators.email, Validators.pattern('[a-z0-9.@]*')]),
'subject': new FormControl(null, Validators.minLength(10)),
'message': new FormControl(null, Validators.required)
});
You can add more Validators by adding them into the array of Validators.
您可以通过将更多验证器添加到验证器数组中来添加它们。
定制验证器 (Custom Validators)
The FormControl class gives you lots of built-in validator functions that cover lots of your use cases. But if you want to add some custom checks for your input values, then you can easily do this using your own validator functions.
FormControl类为您提供了许多内置的验证器函数,这些函数涵盖了许多用例。 但是,如果要为输入值添加一些自定义检查,则可以使用自己的验证器函数轻松地执行此操作。
You can pass custom validator functions along with built-in validators while creating the FormControl object.
创建FormControl对象时,可以将自定义验证器函数与内置验证器一起传递。
export class ContactFormComponent implements OnInit {
public contactForm: FormGroup; public forbiddenUserNames = ['Mack', 'John'];
constructor() { }
ngOnInit() {
this.contactForm = new FormGroup({
'name': new FormControl(Enter Name, [Validators.required, this.forbiddenNames.bind(this)]),
'email': new FormControl(null, [Validators.email, Validators.pattern('[a-z0-9.@]*')]),
'subject': new FormControl(null, Validators.minLength(10)),
'message': new FormControl(null, Validators.required)
});
}
public forbiddenNames(formControl: FormControl): any { if ( this.forbiddenUserNames.indexOf(formControl.value)){ return { 'nameForbidden': true }; } }}
In the above code, we are creating our custom validator function which checks whether the name of the user is valid or not. The forbiddenNames
function takes an argument of FormControl type and checks whether the input name is present in the forbiddenUserNames
array.
在上面的代码中,我们正在创建我们的自定义验证器函数,该函数检查用户名是否有效。 forbiddenNames
函数采用FormControl类型的参数,并检查forbiddenUserNames
数组中是否存在输入名称。
异步验证器 (Async Validators)
As the name defines that the validation is done in an asynchronous manner. When the result of input validators takes some time to validate the input values then we use Async Validators.
顾名思义,验证是以异步方式完成的。 当输入验证器的结果花费一些时间来验证输入值时,我们将使用异步验证器。
Let's create a validator function which responds after 1 second and returns the status of the input whether the input is valid or not. For async validators, we have to return a Promise or an Observable in place of return an object.
让我们创建一个验证器函数,该函数在1秒钟后响应并返回输入的状态,无论输入是否有效。 对于异步验证器,我们必须返回一个Promise或Observable来代替返回一个对象。
export class ContactFormComponent implements OnInit {
public contactForm: FormGroup; public forbiddenUserNames = ['Mack', 'John'];
constructor() { }
ngOnInit() {
this.contactForm = new FormGroup({
'name': new FormControl(Enter Name, [Validators.required, this.forbiddenNames.bind(this)]),
'email': new FormControl(null, [Validators.email, Validators.pattern('[a-z0-9.@]*')], this.forbiddenEmail),
'subject': new FormControl(null, Validators.minLength(10)),
'message': new FormControl(null, Validators.required)
});
}
public forbiddenNames(formControl: FormControl): any { if ( this.forbiddenUserNames.indexOf(formControl.value)){ return { 'nameForbidden': true }; } else { retunr null; }
}
public forbiddenEmail(formControl: FormControl): Promise<any> { return new Promise((resolve, reject)=>{ setTimeout(()=>{ if (formControl.value === 'abc@gmail.com'){ resolve({ 'emailForbidden': true }); } else { resolve(null); }
}, 1000);
}); }}
We have to pass our newly created Async validator function into the third argument of FormControl
object. We can pass a single Async validator or array of async validators as we pass in normal validators.
我们必须将我们新创建的异步验证器函数传递给FormControl
对象的第三个参数。 当我们传递普通验证器时,我们可以传递单个异步验证器或异步验证器数组。
表格数组 (FormArray)
So till now, we have been creating the FormControl
for every input. But what if the user has access to add their FormControls? FormArray
is a class imported from @angular/core
which is used to create dynamic FormControls.
因此,到目前为止,我们一直在为每个输入创建FormControl
。 但是,如果用户有权添加其FormControls怎么办? FormArray
是从@angular/core
导入的类,用于创建动态FormControls。
Let's update our contact form with an additional input hobby and this input will be created by the user.
让我们用其他输入爱好来更新我们的联系表单,此输入将由用户创建。
ngOnInit() { this.contactForm = new FormGroup({
'name': new FormControl(Enter Name, [Validators.required, this.forbiddenNames.bind(this)]),
'email': new FormControl(null, [Validators.email, Validators.pattern('[a-z0-9.@]*')], this.forbiddenEmail),
'subject': new FormControl(null, Validators.minLength(10)),
'message': new FormControl(null, Validators.required), 'hobbies': new FormArray([])
});}
public addHobby() { (<FormArray>this.contactForm.get('hobbies')).push(new FormControl(null));}
In the above code the addHobby
function will be executed whenever the user clicks on the Add Hobby
button. This function will push the new FormControl into the FormArray. Now bind the hobbies FormArray with our Template.
在上面的代码中,只要用户单击“ Add Hobby
按钮,就会执行addHobby
函数。 此函数会将新的FormControl推入FormArray。 现在将爱好FormArray与我们的模板绑定。
<div formArrayName="hobbies"> <button type="button">Add Hobby</button> <div *ngFor="let hobbyControl of this.contactForm.get('hobbies'); let i=index"> <input type="text" [formControlName"]="i"> </div></div>
In the above code, we are using formArrayName
directive to bind the FormArray like formControlName
for binding the FormControls.
在上面的代码中,我们使用formArrayName
指令像FormControlName一样绑定formControlName
来绑定FormControls。
I hope this article answered most of your questions regarding Angular Reactive Forms. If you have any queries or doubts, feel free to reach out to me in the comment box.
我希望本文能够回答您有关AngularReact形式的大多数问题。 如果您有任何疑问或疑问,请随时在评论框中与我联系。
翻译自: https://www.freecodecamp.org/news/angular-reactive-forms-an-introduction-f9d988ae9251/