簡體   English   中英

如何在Angular2中為表單分配和驗證數組

[英]How to assign and validate arrays to forms in Angular2

我在javascript中的模型( this.profile )有一個名為emails的屬性,它是{email, isDefault, status}的數組

然后我將其定義如下

  this.profileForm = this.formBuilder.group({
    .... other properties here
    emails: [this.profile.emails]
  });

  console.log(this.profile.emails); //is an array
  console.log(this.profileForm.emails); // undefined

在html文件中我用它作為

    <div *ngFor="let emailInfo of profileForm.emails">
        {{emailInfo.email}}
        <button (click)="removeEmail(emailInfo)">
           Remove 
        </button>
    </div>

如果我不在formGroup添加它並將其用作數組 - 如下所示 - 它工作正常,但我有一個業務規則,該數組不應為空,我無法根據長度設置表單驗證這個

  emails : [];
  this.profileForm = this.formBuilder.group({
    .... other properties here
  });

  this.emails = this.profile.emails;
  console.log(this.profile.emails); //is an array
  console.log(this.emails); // is an array

我也試過使用formBuilder.array但是那個是控件數組而不是數據數組。

   emails: this.formBuilder.array([this.profile.emails])

那么我的問題是如何將數組從模型綁定到UI以及如何驗證數組的長度?

我應該如何將數組從模型綁定到UI?

好吧,我更願意將所有來自profile.emails電子郵件推送到formArray ,否則您將獲得值,但不會進行驗證。

我該如何驗證數組的長度?

您可以將Validators.minLength(Number)用作任何其他控件

演示代碼:

零件:

export class AnyComponent implements OnInit {

  profileForm: FormGroup;
  emailsCtrl: FormArray;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit(): void {

    this.emailsCtrl = this.formBuilder.array([], Validators.minLength(ANY_NUMBER));
    this.profile.emails.forEach((email: any) => this.emailsCtrl.push(this.initEmail(email)));

    this.profileForm = this.formBuilder.group({
      // ... other controls
      emails: this.emailsCtrl
    });
  }

  private initEmail = (obj: any): FormGroup => {
    return this.formBuilder.group({
      'email': [obj.email], //, any validation],
      'isDefault': [obj.isDefault] //, any validation]
    });
  }
}

模板:

<div *ngFor="let emailInfo of emailsCtrl.value">
  {{emailInfo.email}}
  <button (click)="removeEmail(emailInfo)">
    Remove
  </button>
</div>
<div *ngIf="emailsCtrl.hasError('minlength')">
  It should have at least {{emailsCtrl.getError('minlength').requiredLength}} emails
</div>

PS1:請注意, Validators.minLength(param) 方法的 Validators.minLength(param)必須大於1,否則將無法驗證。

正如您在源代碼中看到的那樣,當控件為空時,它會自動返回null。

然后,為了使其按預期工作,您可以添加required Validator

this.emailsCtrl = this.formBuilder.array([], Validators.compose([Validators.required, Validators.minLength(ANY_NUMBER > 1)]);

在模板中:

<div *ngIf="emailsCtrl.invalid">
  <span *ngIf="emailsCtrl.hasError('required')">
    It's required
  </span>
  <span *ngIf="emailsCtrl.hasError('minlength')">
    It should have at least {{emailsCtrl.getError('minlength').requiredLength}} emails
  </span>
</div>

PS2:

我認為在removeEmail 函數中傳遞要刪除的電子郵件的索引更有意義,因此您不必調用indexOf來獲取特定 email的索引。 你可以這樣做:

<div *ngFor="let emailInfo of emailsCtrl.value; let i = index">
  {{emailInfo.email}}
  <button (click)="removeEmail(i)">
    Remove
  </button>
</div>

零件:

removeEmail(i: number): void {
  this.emailsCtrl.removeAt(i);
}

看看這個簡單的DEMO

這適用於我(角度2.1.2),這種方法使您可以靈活地為電子郵件定義自定義驗證:

 this.profileForm = this.formBuilder.group({
    emails: [this.profile.emails, FormValidatorUtils.nonEmpty]
    // ......
  });

export class FormValidatorUtils {

  static nonEmpty(control: any) {
    if (!control.value || control.value.length === 0) {
      return { 'noElements': true };
    }
    return null;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM