In diesem Artikel geht es um das responsive Formular in Angular und ich hoffe, dass es für alle hilfreich ist, die einfache Methode zur Formularimplementierung vorzustellen.
Aufgrund des kürzlich erfolgten Upgrades des Unternehmens-Frameworks wurde die ursprüngliche Methode der manuellen Formularprüfung aufgegeben und alle Formulare auf responsive umgestellt. Da ich sie noch nie zuvor verwendet hatte, dachte ich zunächst, ich wäre der Einzige, der dies tut Nachdem ich die Gruppe verstanden hatte, stellte ich fest, dass die meisten meiner anderen Kollegen nicht sehr vertraut damit waren Ich musste einige Fallstricke überwinden und habe natürlich auch einige Zeit mit dem Lernen verbracht. Für diejenigen, die damit vertraut sind, ist es zwar sehr einfach, aber es ist dennoch eine Art Verfeinerung, den Lernprozess zusammenzufassen und zusammenzufassen als Methoden zur Lösung der Probleme. Hier geht es eher darum, Theorie mit tatsächlichen Geschäftsanforderungen zu verbinden, anstatt blind API-Einführungen in Form offizieller Dokumente zu schreiben. In diesem Fall handelt es sich um Studiennotizen und nicht um eine Zusammenfassung.
Warum führen wir hauptsächlich responsive Formulare ein? Weil reaktive Formulare direkten, expliziten Zugriff auf das zugrunde liegende
Form Object Modelbieten. Sie sind robuster als vorlagengesteuerte Formulare: Sie sind erweiterbarer, wiederverwendbar und testbarer. Es ist für komplexere Formen geeignet. Das Wichtigste ist, dass ich nicht weiß, wie man andere Dinge macht. [Verwandte Tutorial-Empfehlungen: „angular Tutorial“]1. Grundkonzepte responsiver Formulare
1.FormControl, FormArray, FormGroup1.FormControl
: Wird verwendet, um den Wert eines einzelnen Formulars zu verfolgen Formularsteuerung und Validierungsstatus, z. B. eine Feldbindung//初始化一个栏位的值为测试名字,并且不可用 const Name:FormControl = new FormControl({value:'测试名字', disabled: true });
//定义表单对象的属性为aliases的FormArray this.validateForm = this.fb.group({aliases: this.fb.array([]),}); //获取FormArray get aliases() {return this.validateForm.get('aliases') as FormArray;} //给FormArray 添加item this.aliases.push( this.fb.group({Id: 0,Name: [null],}) );
validateForm = new FormGroup({Name: new FormControl({value:'测试名字', disabled: true }),}); validateForm = this.fb.group({});
2. Um dies sicherzustellen, wird die Formularvalidierung verwendet die Eingaben des Nutzers vollständig und richtig sind. So fügen Sie einem Formularsteuerelement einen einzelnen Validator hinzu und zeigen den Gesamtstatus des Formulars an. Normalerweise gibt der Validator null zurück, um anzugeben, dass alle Validierungen erfolgreich waren.
1.Synchroner Validator: Die synchrone Validatorfunktion akzeptiert eine Kontrollinstanz und gibt dann eine Reihe von Validierungsfehlern oder zurück, die als zweiter Parameter beim Instanziieren des FormControl
validateForm!: FormGroup; //手动创建 validateForm = new FormGroup({ Name: new FormControl('测试名字'), }); //FormBuilder表单构建器 validateForm = this.fb.group({ Name:[ { value:'测试名字',disabled:true}], });
//formControlName的值必须和ts代码中FormControl 的实例一致 <input type="text" id="name" class="form-control" formControlName="name" required> //判断对应的FormControl 是否没通过校验 而有错误信息 <div *ngIf="name.errors?.['required']"> Name is required. </div>
übergeben werden können : Die asynchrone Funktion akzeptiert eine Kontrollinstanz und gibt ein Promise oder Observable zurück, nachdem alle synchronen Validatoren bestanden haben. Sie können es als dritten Parameter übergeben, wenn Sie das FormControl instanziieren Validator
: Um beispielsweise einige Längen zu überprüfen, die nicht leer sein dürfen, können Sie die bereitgestellte Validator-Klasse verwenden, um dies zu erreichen.4.Benutzerdefinierter Validatornull
: Der im System bereitgestellte Validator kann bestehende Anforderungen nicht erfüllen Benutzerdefinierter Validator, um eine personalisierte Überprüfung durchzuführen. Der benutzerdefinierte Validator muss den Typ ValidationErrors zurückgeben oder leer sein
3. Grundlegende Methoden und Attribute von Formularen und Elementen status, um den Status im FormControl-Steuerelement abzurufen 1. 简单的表单实现 ###### 我们主要用到的框架版本是Angular 12 + NG-ZORRO, 所以在下面很多实现和示例代码将与他们有关,虽然可能代码不一样,但也只是在UI层面的区别稍微大一点点,但对于TS代码,只是换汤不换药,稍微注意一下就好了,其实下面实例中的需求,基本就是我在工作时需要做的的一些基本内容和遇到的问题,经过查阅资料后解决的思路和过程,甚至截图都一模一样。 实现最基本的表单新增功能并且校验员工ID为必填以及长度不能超过50,要实现的效果图如下 1.首先需求未提出有特殊注意点,基本都是简单的输入框赋值然后保存,只要基本的概念搞清楚实现这种最简单 2.我们用一个FormGroup和6个FormControl 完成和界面绑定即可 3.绑定验证器用于校验长度和必填 1.定义html 表单结构 2.在TypeScript代码中声明表单对象,在构造函数中注入FormBuilder,并且在ngOnInit中进行表单初始化 2.在表格中应用表单 需要实现表格的表单新增和提交以及个性化定制需求,要实现的效果图和需求描述如下 1.点击Add 添加一行表格 ,编辑完毕,点击Save保存数据,点击Revoke取消编辑 2.默认开始时间和结束时间禁止使用 3.当选择Contract Type为 “短期合同” Contract start date 和Contract end date可用,当选择Contract Type为 “长期合同”不可用 4.如果Contract start date 和Contract end date可用,需要验证开始结束时间合法性,例如开始事件不能超过结束时间 1.在表格中使用表单,虽然表单在表格中,但是他的每一列同样都是一个个FormControl 2.一共4列需要输入值,就说明有4个FormControl 然后最后一列就是2个按钮 3.我们根据上面的基础知识知道,FormControl 不能单独使用,所以需要被FormGroup包裹,此时说明一行对应一个FormGroup 4.由一行对应一个FormGroup知道,我们的表格时多行的,也就是有多个FormGroup,我们可以使用FormArray来存储,因为他代表一组表单组 5.根据需求第2点默认开始时间和结束时间禁止使用,我们知道在一开始初始化时,设置开始结束时间对应的FormControl 为disabled就行了 6.第3点需求需要涉及联动,也就是当Contract Type对应的FormControl 的值为“短期合同”时,需要将 “开始结束时间”对应的FormControl设置为可用,这个需要自定义验证器来完成 1.首先定义Html表单结构 2.在TypeScript代码中声明表单对象validateForm,然后初始化一个FormArray类型的属性aliases的实例作为表格formArrayName的值 3.点击Add按钮时向表单对象validateForm的属性aliases添加一条数据 4.定义Contract Type 联动的自定义校验器 contractTypeValidation()方法 5.定义时间校验器 timeValidation()方法,如果时间不合法,将FormControl的错误状态设置属性beginGtendDate,然后在模板中根据这个属性来选择是否渲染日式信息 更多编程相关知识,请访问:编程入门!! Das obige ist der detaillierte Inhalt vonEine kurze Analyse responsiver Formulare in Angular. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!patchValue()
reset () Mit patchValue können Sie auch den Wert von FormControl nach Bedarf festlegen, ohne ihn vollständig festzulegen. Wird in FormControl verwendet, um alle Zustände des aktuellen Steuerelements zurückzusetzen. Wird in FormGroup verwendet, um den Inhalt im Formularobjekt zurückzusetzen. Wenn das Steuerelement beispielsweise auf deaktiviert gesetzt ist, wird control.reset({ Wert: 'Drew', deaktiviert: true }); markAsPristine() Diese Methode wird hauptsächlich verwendet, wenn das Formular zurückgesetzt wird true markAsDirty() Es dient dazu, den Formular-FormControl-Steuerwert als geändert zu markieren. Zu diesem Zeitpunkt ist sein Status „Dirty“ wahr und Validierungsstatus usw. setValidators() Legen Sie Validatoren für das FormControl-Steuerelement fest, verwenden Sie das Array „setValidators([v1,v2,v3])“ disable() Legen Sie fest, dass das FormControl-Steuerelement nicht verfügbar ist. Beachten Sie, dass der entsprechende Wert des regulären Werts getValue() des Formulars leer ist. Sie können getRawValue() verwenden, um den ursprünglichen Wert abzurufen Objekt, um den Wert des entsprechenden FormControl abzurufen. enable() , um das FormControl-Steuerelement „Enable“ festzulegen Eigenschaft Anleitung zur Verwendung touched Wenn der touched-Wert des FormControl-Steuerelements wahr ist, bedeutet dies, dass das Steuerelement den Fokus erhalten hat und umgekehrt untouched Wenn untouched wahr ist , bedeutet dies, dass das Steuerelement nicht den Fokus erlangt hat, und umgekehrt um anzuzeigen, dass das Formularelement vom Benutzer bedient wurde. Sie können die Methode markAsDirty verwenden, um es auf true zu setzendirty Fehler
Erhalten Sie die Fehlerinformationen der aktuellen Steuerung 二.实例分析及应用
需求1
分析
实现步骤
<!-- formGroup 属性绑定表单对象 -->
<form nz-form [formGroup]="validateForm" nzLayout="vertical">
<nz-form-label nzRequired>Employee ID
</nz-form-label>
<!-- Employee_ErrorTrip为验证不通过弹出的提示信息 -->
<!-- formControlName绑定表单元素FormControl -->
<nz-form-control [nzErrorTip]="Employee_ErrorTrip">
<input nz-input formControlName="EmployeeID" placeholder="" />
</nz-form-control>
<ng-template #Employee_ErrorTrip let-control>
<ng-container *ngIf="control.hasError('required')">
员工编号为必填项目
</ng-container>
</ng-template>
</form>
//定义表单对象
validateForm:FormGroup;
//构造函数注入FormBuilder
constructor(private fb: FormBuilder){}
//在声明周期钩子函数中初始化表单
ngOnInit() {
//初始化并且绑定必填验证器和长度验证器
this.validateForm = this.fb.group({
EmployeeID: ['', [Validators.required, Validators.maxLength(50)]],
})
}
需求2
分析
实现步骤
<nz-table [nzData]="CONTRACTS" nzTableLayout="fixed" [nzShowQuickJumper]="true">
<thead>
<tr>
<th>Contract type</th>
<th>Contract start date</th>
<th>Contract end date</th>
<th>Agreement item</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<!-- 绑定表单组属性aliases -->
<ng-container formArrayName="aliases">
<!-- 将表单组中当前行的索引与formGroup绑定 -->
<tr [formGroupName]="i" *ngFor="let data of aliases.controls;index as i">
<td>
<nz-form-item>
<nz-form-control nzSpan="1-24">
<!-- AccountName绑定FormControl -->
<nz-select nzShowSearch nzAllowClear nzPlaceHolder="" formControlName="Type">
<nz-option *ngFor="let option of Type" [nzValue]="option.Code" [nzLabel]="option.Value">
</nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control nzSpan="1-24" [nzErrorTip]="StartDate">
<nz-date-picker id="StartDate" formControlName="StartDate" nzPlaceHolder="">
</nz-date-picker>
<!-- 校验提示模板用于时间验证器 -->
<ng-template #StartDate let-control>
<!-- 判断时间验证器是否存在beginGtendDate属性,如果有说明没有通过验证 然后展示提示信息 -->
<ng-container *ngIf="control.hasError('beginGtendDate')">
开始时间不能晚于结束时间
</ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control nzSpan="1-24" [nzErrorTip]="EndDate">
<nz-date-picker style="width: 100%;" formControlName="EndDate" nzPlaceHolder="">
</nz-date-picker>
<ng-template #EndDate let-control>
<ng-container *ngIf="control.hasError('beginGtendDate')">
开始时间不能晚于结束时间
</ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control nzSpan="1-24">
<nz-select nzShowSearch nzAllowClear nzPlaceHolder="" formControlName="ContractType">
<nz-option *ngFor="let option of ContractTypes" [nzValue]="option.Code" [nzLabel]="option.Value">
</nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
</td>
<td>
<button style="color: #009688;" nz-button nzType="text">
<i nz-icon nzType="save"></i>Save
</button>
<button nz-button nzType="text" nzDanger>
<i nz-icon nzType="redo"></i>Revoke
</button>
</td>
</tr>
</ng-container>
</tbody>
</nz-table>
//定义表单对象
validateForm:FormGroup;
//构造函数注入FormBuilder
constructor(private fb: FormBuilder){}
//在声明周期钩子函数中初始化一个表单对象validateForm
ngOnInit() {
this.validateForm = this.fb.group({
aliases: this.fb.array([]),
});
}
//声明aliases属性用作界面formArrayName绑定
get aliases(){
return this.validateForm.get('aliases') as FormArray;
}
addNewRow() {
const group = this.fb.group({
//添加给Type初始化验证器
Type: [null, [CommonValidators.required, this.contractTypeValidation()]],
//初始化禁用StartDate和EndDate的FormControl
StartDate: [{ value: null, disabled: true }, []],
EndDate: [{ value: null, disabled: true },[]],
ContractType: [null, [CommonValidators.required, CommonValidators.maxLength(20)]],
})
this.aliases.push(group);
}
//自定义Contract Type验证器
contractTypeValidation() {
return (control: AbstractControl): ValidationErrors | null => {
let contents: any[] = this.validateForm.value.aliases;
if (control.touched && !control.pristine) {
//获取表单组
const formArray: any = this.validateForm.controls.aliases;
//找到正在编辑的行的索引
const index = contents.findIndex((x) => !x.isShowEdit);
//获取开始结束时间FormControl 实例
const StartDate: AbstractControl =
formArray.controls[index].get('StartDate'),
EndDate: AbstractControl = formArray.controls[index].get('EndDate');
if (control.value === "短期合同") {
//给开始结束时间设置验证器用于验证时间合法性
StartDate.setValidators([CommonValidators.required, this.timeValidation()]);
EndDate.setValidators([this.timeValidation()]);
//启动开始结束时间控件
EndDate.enable();
StartDate.enable();
} else {
//Contract Type不是短期合同就清除验证器
StartDate.clearValidators();
EndDate.clearValidators();
//禁用开始结束时间
EndDate.disable();
StartDate.disable();
}
}
return null;
}
}
//自定义时间验证器
timeValidation()
{
return (control: AbstractControl): ValidationErrors | null => {
if (!control.pristine) {
let contents: any[] = this.validateForm.value.aliases;
const formArray: any = this.validateForm.controls.aliases;
const index = contents.findIndex((x) => !x.isShowEdit);
//获取开始结束时间FormControl实例
const EndDate: string = formArray.controls[index].get('EndDate').value;
const StartDate: string =formArray.controls[index].get('StartDate').value;
if (EndDate === null || StartDate === null) return null;
//如果时间不合法,那就设置当前控件的错误状态 beginGtendDate为true
if (
Date.parse(control.value) > Date.parse(EndDate) ||
Date.parse(control.value) < Date.parse(StartDate)
) {
return { beginGtendDate: true };
}
}
return null;
}
}