web-dev-qa-db-ja.com

Angular 2+材料mat-chip-list formArray検証

mat-chipmat-chip-listに追加されたことを確認するにはどうすればよいですか。 ReactiveFormsを使用しています。 requiredバリデーターで試しました。

値は名前のリストにすることができるため、フォームを送信する前に、名前のリストに少なくとも1つの名前があることを確認する必要があります。リストが空の場合、mat-errorにエラーメッセージが表示されます。 requiredバリデーターを使用すると、リストに名前を追加しても、フォームが無効になります。

編集:反応型フォーム

カスタムバリデーターを作成しようとしましたが、現在テンプレート駆動型フォームの代わりにリアクティブフォームを使用していますが、機能させることができません。以下のコードを編集して自分の変更を反映し、これを作成しました https://stackblitz.com/edit/angular-4d5vfj

[〜#〜] html [〜#〜]

<form [formGroup]="myForm">
  <mat-form-field class="example-chip-list">
    <mat-chip-list #chipList formArrayName="names">
      <mat-chip *ngFor="let name of myForm.get('names').controls; let i=index;"
        [formGroupName]="i"
        [selectable]="selectable"
        [removable]="removable"
        (removed)="remove(myForm, i)">
        <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
      </mat-chip>

       <input placeholder="Names"
          [matChipInputFor]="chipList"
          [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
          [matChipInputAddOnBlur]="addOnBlur"
          (matChipInputTokenEnd)="add($event, asset)">
    </mat-chip-list>
    <mat-error>Atleast 1 name need to be added</mat-error>
  </mat-form-field>
</form>

[〜#〜] ts [〜#〜]

import {COMMA, ENTER} from '@angular/cdk/keycodes';
import {Component} from '@angular/core';
import {FormGroup, FormControl, FormBuilder, FormArray} from '@angular/forms';
import {MatChipInputEvent} from '@angular/material';

@Component({
  selector: 'chip-list-validation-example',
  templateUrl: 'chip-list-validation-example.html',
  styleUrls: ['chip-list-validation-example.css'],
})
export class ChipListValidationExample {
  public myForm: FormGroup;

  // name chips
  visible = true;
  selectable = true;
  removable = true;
  addOnBlur = true;
  readonly separatorKeysCodes: number[] = [ENTER, COMMA];

  // data
  data = {
    names: ['name1', 'name2']
  }

  constructor(private fb: FormBuilder) {
    this.myForm = this.fb.group({
      names: this.fb.array(this.data.names, this.validateArrayNotEmpty)
    });
  }

  initName(name: string): FormControl {
    return this.fb.control(name);
  }

  validateArrayNotEmpty(c: FormControl) {
    if (c.value && c.value.length === 0) {
      return { 
        validateArrayNotEmpty: { valid: false }
      };
    }
    return null;
  }

  add(event: MatChipInputEvent, form: FormGroup): void {
    const input = event.input;
    const value = event.value;

    // Add name
    if ((value || '').trim()) {
      const control = <FormArray>form.get('names');
      control.Push(this.initName(value.trim()));
      console.log(control);
    }

    // Reset the input value
    if (input) {
      input.value = '';
    }
  }

  remove(form, index) {
    console.log(form);
    form.get('names').removeAt(index);
  }
}
5
Asgher Qureshi

問題は、chipListerrorStateステータスがtrueの場合、chipListFormArrayINVALIDに設定されないことです。 。

私は同じ問題に直面していますが、これがそのままではうまくいかない理由や、chipListの形式がFormArrayになっているためにこれを暗黙的に実現できる方法がわかりません。

この問題を解決するには、FormArrayからのステータス変更をリッスンし、chipListerrorStateを手動で設定します。

@ViewChild('chipList') chipList: MatChipList;

ngOnInit() {
  this.myForm.get('names').statusChanges.subscribe(status => 
     this.chipList.errorState = status === 'INVALID' ? true : false);
}

https://stackblitz.com/edit/angular-4d5vfj-rembhd

1
fridoo