国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Angualr響應(yīng)式表單

這篇具有很好參考價(jià)值的文章主要介紹了Angualr響應(yīng)式表單。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

由于最近公司框架升級(jí),拋棄了原來手動(dòng)檢驗(yàn)表單的方式,將所有的表單改為響應(yīng)式,由于之前沒用過,在一開始我以為只有我沒有用過,了解了小組里的其他同事得知基本都不是很熟悉

后面時(shí)間比較緊,沒辦法只能邊做邊學(xué)邊改了,所以難免踩了一些坑,當(dāng)然也花了一些時(shí)間學(xué)習(xí),雖然對(duì)于熟悉的人來說可能很簡單,但是還是將學(xué)習(xí)的過程和小結(jié)以及解決的問題的方法總結(jié)一下,也算是一種提煉。在這里更多的是理論結(jié)合實(shí)際業(yè)務(wù)需求來說,而不是一味的按照官方文檔的方式寫API介紹,如果那樣就是學(xué)習(xí)筆記,而不是總結(jié)了。

為什么主要介紹響應(yīng)式表單呢?因?yàn)轫憫?yīng)式表單提供對(duì)底層表單對(duì)象模型直接、顯式的訪問。它們與模板驅(qū)動(dòng)表單相比,更加健壯:它們的可擴(kuò)展性、可復(fù)用性和可測試性都更高。適用于比較復(fù)雜的表單,其實(shí)最重要的是其他的我也不會(huì)呀。

一、響應(yīng)式表單基本概念

1.FormControl 、FormArray 、FormGroup

1.FormControl: 用于追蹤單個(gè)表單控件的值和驗(yàn)證狀態(tài),例如一個(gè)欄位綁定

//初始化一個(gè)欄位的值為測試名字,并且不可用
const Name:FormControl = new FormControl({value:'測試名字', disabled: true });

2.FormArray:用于追蹤表單控件數(shù)組的值和狀態(tài),例如幾個(gè)欄位一起,常用的表格或者在表單中嵌入表格

//定義表單對(duì)象的屬性為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],})
);

3.FormGroup:用于追蹤單個(gè)表單控件的值和驗(yàn)證狀態(tài),它可以包含單個(gè)或多個(gè)FormControl 和 FormArray ,一般一個(gè)表單對(duì)應(yīng)一個(gè)FormGroup實(shí)例,而表單的各個(gè)欄位對(duì)應(yīng)FormControl 和FormArray ,當(dāng)然他們可以互相嵌套,例如FormArray 中可以嵌套FormGroup,它的靈活性就是如此。

validateForm =  new FormGroup({Name: new FormControl({value:'測試名字', disabled: true }),});
validateForm = this.fb.group({});

4.FormBuilder:是一個(gè)可注入的服務(wù)提供者,手動(dòng)創(chuàng)建多個(gè)表單控件實(shí)例會(huì)非常繁瑣,F(xiàn)ormBuilder 服務(wù)提供了一些便捷方法來生成表單控件,以前每一個(gè)創(chuàng)建要先生成FormGroup 然后生成FormControl,而使用FormBuilder的group方法可以減少重復(fù)代碼,說白了就是幫助方便生成表單

validateForm!: FormGroup;
//手動(dòng)創(chuàng)建
validateForm = new FormGroup({
    Name: new FormControl('測試名字'),
  });
  
//FormBuilder表單構(gòu)建器
validateForm = this.fb.group({
  Name:[ { value:'測試名字',disabled:true}],
});



2.Validator 表單驗(yàn)證

表單驗(yàn)證用于確保用戶的輸入是完整和正確的。如何把單個(gè)驗(yàn)證器添加到表單控件中,以及如何顯示表單的整體狀態(tài),通常驗(yàn)證器返回null表示所有的驗(yàn)證通過。


1.同步驗(yàn)證器:同步驗(yàn)證器函數(shù)接受一個(gè)控件實(shí)例,然后返回一組驗(yàn)證錯(cuò)誤或 null,在實(shí)例化FormControl 時(shí)可以將他作為第二個(gè)參數(shù)傳入

 //formControlName的值必須和ts代碼中FormControl 的實(shí)例一致
 <input type="text" id="name" class="form-control" formControlName="name" required>
 
 //判斷對(duì)應(yīng)的FormControl 是否沒通過校驗(yàn) 而有錯(cuò)誤信息
 <div *ngIf="name.errors?.['required']">
    Name is required.
 </div>
//初始化一個(gè)欄位并且加入必填校驗(yàn)驗(yàn)證器
const name:FormControl = new FormControl({'測試名字', disabled: true },Validators.required,);

//獲取這個(gè)FormControl
get name() { return this.heroForm.get('name'); }

2.異步驗(yàn)證器:異步函數(shù)接受一個(gè)控件實(shí)例并返回一個(gè) Promise 或 Observable ,只有在所有同步驗(yàn)證器都通過之后,Angular 才會(huì)運(yùn)行異步驗(yàn)證器,在實(shí)例化FormControl 時(shí)可以將他作為第三個(gè)參數(shù)傳入

3.內(nèi)置驗(yàn)證器:例如驗(yàn)證一些長度,不能為空可以使用已經(jīng)提供的Validator 類來實(shí)現(xiàn)


4.自定義驗(yàn)證器:系統(tǒng)內(nèi)部提供的驗(yàn)證器不能滿足現(xiàn)有需求,可以使用自定義驗(yàn)證器做一些個(gè)性化的校驗(yàn),自定義校驗(yàn)器必須返回ValidationErrors類型或者空

 //formControlName的值必須和ts代碼中FormControl 的實(shí)例一致
 <input type="text" id="name" class="form-control" formControlName="name" required>
 
 //判斷對(duì)應(yīng)的FormControl 是否沒通過校驗(yàn) 而有錯(cuò)誤信息
 <div *ngIf="name.hasError('Invalid')">
    名字也太長了吧....
 </div>
//初始化一個(gè)欄位并且加入必填校驗(yàn)驗(yàn)證器
const name:FormControl = new FormControl({'測試名字', disabled: true },this.CustomValidators());

CustomValidators() {
 return (control: AbstractControl): ValidationErrors | null => {
    if(control.value.length!=10)
      {
        return {Invalid:true}
      }
      return null;
    };
}



3.表單及元素的基本方法和屬性

  • 方法
方法 使用效果
setValue() 使用setVlue可以設(shè)置控件FormControl 的值,但是使用時(shí)必須FormGroup所有的屬性一起賦值,不能單個(gè)賦值,常用在修改加載賦值。
patchValue() 使用patchValue也可以設(shè)置FormControl的值,可以根據(jù)需要設(shè)置指定的FormControl,而不需要全部設(shè)置,常用在更新某個(gè)字段值
reset () FormControl 中使用重置當(dāng)前控件所有狀態(tài),F(xiàn)ormGroup中使用就是重置表單對(duì)象里的內(nèi)容,例如控件被設(shè)為不可用disabled,control.reset({ value: 'Drew', disabled: true });
markAsPristine() 是將表單控件值標(biāo)記為未改變,這個(gè)方法主要用在表單重置時(shí),此時(shí)它的狀態(tài)pristine為true
markAsDirty() 是將表單FormControl 控件值標(biāo)記為已改變,此時(shí)它的狀態(tài)Dirty為true
updateValueAndValidity() 重新計(jì)算表單FormControl 控件的值和驗(yàn)證狀態(tài)等
setValidators() 給表單FormControl 控件設(shè)置驗(yàn)證器,如果設(shè)置多個(gè)就用數(shù)組"setValidators([v1,v2,v3])" ,串行設(shè)置是覆蓋的關(guān)系,不是追加
disable() 給表單FormControl 控件設(shè)置不可用,注意當(dāng)FormControl 是disabled時(shí),表單的常規(guī)取值getValue()對(duì)應(yīng)值會(huì)為空,可用getRawValue()取原始值對(duì)象得到對(duì)應(yīng)FormControl 的值
enable() 給表單FormControl 控件設(shè)置啟用

  • 屬性
屬性 使用方法說明
touched 當(dāng)表單FormControl 控件 的touched為true表示控件已經(jīng)被獲取焦點(diǎn),反之同理
untouched 當(dāng)untouched 為true表示控件未被獲取焦點(diǎn),反之同理
pristine 表示表單元素是純凈的,用戶未操作過,可以使用markAsPristine方法設(shè)為true
dirty 表示表單元素是已被用戶操作過,可以使用markAsDirty方法設(shè)為true
status 獲取表單FormControl 控件上的的狀態(tài)
Errors 獲取當(dāng)前控件的錯(cuò)誤信息



二.實(shí)例分析及應(yīng)用

1. 簡單的表單實(shí)現(xiàn)
需求1

我們主要用到的框架版本是Angular 12 + NG-ZORRO, 所以在下面很多實(shí)現(xiàn)和示例代碼將與他們有關(guān),雖然可能代碼不一樣,但也只是在UI層面的區(qū)別稍微大一點(diǎn)點(diǎn),但對(duì)于TS代碼,只是換湯不換藥,稍微注意一下就好了,其實(shí)下面實(shí)例中的需求,基本就是我在工作時(shí)需要做的的一些基本內(nèi)容和遇到的問題,經(jīng)過查閱資料后解決的思路和過程,甚至截圖都一模一樣。

實(shí)現(xiàn)最基本的表單新增功能并且校驗(yàn)員工ID為必填以及長度不能超過50,要實(shí)現(xiàn)的效果圖如下

Angualr響應(yīng)式表單

分析

1.首先需求未提出有特殊注意點(diǎn),基本都是簡單的輸入框賦值然后保存,只要基本的概念搞清楚實(shí)現(xiàn)這種最簡單

2.我們用一個(gè)FormGroup和6個(gè)FormControl 完成和界面綁定即可

3.綁定驗(yàn)證器用于校驗(yàn)長度和必填

實(shí)現(xiàn)步驟

1.定義html 表單結(jié)構(gòu)

<!-- formGroup 屬性綁定表單對(duì)象 -->
<form nz-form [formGroup]="validateForm" nzLayout="vertical">
  <nz-form-label nzRequired>Employee ID
  </nz-form-label>
  
   <!-- Employee_ErrorTrip為驗(yàn)證不通過彈出的提示信息 -->
   <!-- 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')">
      員工編號(hào)為必填項(xiàng)目
    </ng-container>
  </ng-template>
</form>

2.在TypeScript代碼中聲明表單對(duì)象,在構(gòu)造函數(shù)中注入FormBuilder,并且在ngOnInit中進(jìn)行表單初始化

//定義表單對(duì)象
validateForm:FormGroup;

//構(gòu)造函數(shù)注入FormBuilder
constructor(private fb: FormBuilder){}

//在聲明周期鉤子函數(shù)中初始化表單
ngOnInit() {
  //初始化并且綁定必填驗(yàn)證器和長度驗(yàn)證器

    this.validateForm = this.fb.group({
      EmployeeID: ['', [Validators.required, Validators.maxLength(50)]],  
    })
}

2.在表格中應(yīng)用表單
需求2

需要實(shí)現(xiàn)表格的表單新增和提交以及個(gè)性化定制需求,要實(shí)現(xiàn)的效果圖和需求描述如下

1.點(diǎn)擊Add 添加一行表格 ,編輯完畢,點(diǎn)擊Save保存數(shù)據(jù),點(diǎn)擊Revoke取消編輯

2.默認(rèn)開始時(shí)間和結(jié)束時(shí)間禁止使用

3.當(dāng)選擇Contract Type為 “短期合同” Contract start date 和Contract end date可用,當(dāng)選擇Contract Type為 “長期合同”不可用

4.如果Contract start date 和Contract end date可用,需要驗(yàn)證開始結(jié)束時(shí)間合法性,例如開始事件不能超過結(jié)束時(shí)間

Angualr響應(yīng)式表單

分析

1.在表格中使用表單,雖然表單在表格中,但是他的每一列同樣都是一個(gè)個(gè)FormControl

2.一共4列需要輸入值,就說明有4個(gè)FormControl 然后最后一列就是2個(gè)按鈕

3.我們根據(jù)上面的基礎(chǔ)知識(shí)知道,F(xiàn)ormControl 不能單獨(dú)使用,所以需要被FormGroup包裹,此時(shí)說明一行對(duì)應(yīng)一個(gè)FormGroup

4.由一行對(duì)應(yīng)一個(gè)FormGroup知道,我們的表格時(shí)多行的,也就是有多個(gè)FormGroup,我們可以使用FormArray來存儲(chǔ),因?yàn)樗硪唤M表單組

5.根據(jù)需求第2點(diǎn)默認(rèn)開始時(shí)間和結(jié)束時(shí)間禁止使用,我們知道在一開始初始化時(shí),設(shè)置開始結(jié)束時(shí)間對(duì)應(yīng)的FormControl 為disabled就行了

6.第3點(diǎn)需求需要涉及聯(lián)動(dòng),也就是當(dāng)Contract Type對(duì)應(yīng)的FormControl 的值為“短期合同”時(shí),需要將 “開始結(jié)束時(shí)間”對(duì)應(yīng)的FormControl設(shè)置為可用,這個(gè)需要自定義驗(yàn)證器來完成

實(shí)現(xiàn)步驟

1.首先定義Html表單結(jié)構(gòu)

<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">
      <!-- 將表單組中當(dāng)前行的索引與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>
              <!-- 校驗(yàn)提示模板用于時(shí)間驗(yàn)證器 -->
              <ng-template #StartDate let-control>
              	<!-- 判斷時(shí)間驗(yàn)證器是否存在beginGtendDate屬性,如果有說明沒有通過驗(yàn)證 然后展示提示信息 -->
                <ng-container *ngIf="control.hasError('beginGtendDate')">
                  開始時(shí)間不能晚于結(jié)束時(shí)間
                </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')">
                  開始時(shí)間不能晚于結(jié)束時(shí)間
                </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>

2.在TypeScript代碼中聲明表單對(duì)象validateForm,然后初始化一個(gè)FormArray類型的屬性aliases的實(shí)例作為表格formArrayName的值

3.點(diǎn)擊Add按鈕時(shí)向表單對(duì)象validateForm的屬性aliases添加一條數(shù)據(jù)

4.定義Contract Type 聯(lián)動(dòng)的自定義校驗(yàn)器 contractTypeValidation()方法

5.定義時(shí)間校驗(yàn)器 timeValidation()方法,如果時(shí)間不合法,將FormControl的錯(cuò)誤狀態(tài)設(shè)置屬性beginGtendDate,然后在模板中根據(jù)這個(gè)屬性來選擇是否渲染日式信息文章來源地址http://www.zghlxwxcb.cn/news/detail-807338.html

//定義表單對(duì)象
validateForm:FormGroup;
//構(gòu)造函數(shù)注入FormBuilder
constructor(private fb: FormBuilder){}

//在聲明周期鉤子函數(shù)中初始化一個(gè)表單對(duì)象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初始化驗(yàn)證器
    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驗(yàn)證器
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);

        //獲取開始結(jié)束時(shí)間FormControl 實(shí)例
        const StartDate: AbstractControl =
          formArray.controls[index].get('StartDate'),
          EndDate: AbstractControl = formArray.controls[index].get('EndDate');

        if (control.value === "短期合同") {
          //給開始結(jié)束時(shí)間設(shè)置驗(yàn)證器用于驗(yàn)證時(shí)間合法性
          StartDate.setValidators([CommonValidators.required, this.timeValidation()]);
          EndDate.setValidators([this.timeValidation()]);

          //啟動(dòng)開始結(jié)束時(shí)間控件
          EndDate.enable();
          StartDate.enable();
        } else {
          //Contract Type不是短期合同就清除驗(yàn)證器
          StartDate.clearValidators();
          EndDate.clearValidators();
          //禁用開始結(jié)束時(shí)間
          EndDate.disable();
          StartDate.disable();
        }

      }
      return null;
    }
  }



  //自定義時(shí)間驗(yàn)證器
 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);
        //獲取開始結(jié)束時(shí)間FormControl實(shí)例
        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;

        //如果時(shí)間不合法,那就設(shè)置當(dāng)前控件的錯(cuò)誤狀態(tài) beginGtendDate為true
        if (
          Date.parse(control.value) > Date.parse(EndDate) ||
          Date.parse(control.value) < Date.parse(StartDate)
        ) {
          return { beginGtendDate: true };
        }
      }
      return null;
    }
  }

到了這里,關(guān)于Angualr響應(yīng)式表單的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包