【问题标题】:Mat-Error Required validation error message shows when form is first openMat-Error 首次打开表单时显示必需的验证错误消息
【发布时间】:2021-12-24 08:17:06
【问题描述】:

我有一个自定义控件组件,用于显示 mat-chip-lists 所需的验证错误。在我使用此组件的表单上,当我第一次打开此表单时,会显示所需的验证消息。我只希望它在字段未填充任何数据时显示。有人可以提供一个原因和解决方案,我需要做什么才能使验证正常工作。

我可能过于复杂了,它比我想象的要简单得多。

html where mat-error element for required show:

<mat-form-field [floatLabel]="floatLabel">
 <mat-label>{{ label }}</mat-label>
  <mat-chip-list #optionList aria-label="label" required>
   <mat-chip *ngFor="let item of selectedOptions" (removed)="removed(item)" 
 [removable]="!item.disabled" [disabled]="item.disabled">
  {{ item.text }}
  <mat-icon *ngIf="!item.disabled" matChipRemove>cancel</mat-icon>
</mat-chip>
  <input
  #optionInput
  type="text"
  [placeholder]="placeholder"
  [formControl]="formControl"
  [matAutocomplete]="optionAutoComplete"
  [matChipInputFor]="optionList"
  [required]="required"
  />
</mat-chip-list>
<mat-autocomplete #optionAutoComplete="matAutocomplete" 
 (optionSelected)="selected($event.option.value)">
  <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
  {{ option.text }}
  </mat-option>
 </mat-autocomplete>
 <mat-hint *ngIf="hint">{{ hint }}</mat-hint>
 </mat-form-field>
 <mat-error *ngIf="required === true && hasValue === false && 
        isInitialized === true"> {{ label }} is 
 <strong>required</strong> </mat-error>

自定义控件的打字稿 当您从列表中删除选定项目时,将触发已删除函数。它重新打开检查并将更新发送到父组件。

 Component({
  selector: 'app-chips',
  templateUrl: './chips.component.html',
 })
 export class ChipsComponent implements OnInit, DoCheck {
  @Input() label = '';
  @Input() placeholder = '';
  @Input() options: Options[] = [];
  @Input() selectedOptions: Options[] = [];
  @Input() floatLabel: FloatLabelType = 'auto';
  @Input() hint!: string | undefined;
  @Input() required = true;
  hasValue: boolean = this.selectedOptions.length > 0;
  isInitialized: boolean | undefined;

 @ViewChild('optionInput') optionInput: ElementRef | undefined;

 @Output() onRemoved = new EventEmitter<Options>();
 @Output() selectedOptionsChanged = new EventEmitter<Options[]>();

formControl = new FormControl('');
filteredOptions: Observable<Options[]> | undefined;

iterableDiffer: IterableDiffer<Options>;

constructor(private readonly iterableDiffers: IterableDiffers) {
   this.iterableDiffer = this.iterableDiffers.find([]).create();
 }

 ngDoCheck(): void {
  const optionChanges = this.iterableDiffer.diff(this.options);
   if (optionChanges) {
    this.filteredOptions = of(this.options);
   }
   if (this.required === undefined) {
    this.required = false;
   }
 }

 ngOnInit(): void {
   this.subscribeFilterOptions();
   this.isInitialized = true;
}

    ngAfterViewInit(): void {
     this.isInitialized = true;
     }

 selected(value: Options): void {
  if (this.optionInput) {
    this.optionInput.nativeElement.value = '';
   }
   if (!this.selectedOptions.find((x) => x.text === value.text)) {
    this.selectedOptions.push(value);
    this.selectedOptionsChanged.emit(this.selectedOptions);
  }
  this.hasValue = this.selectedOptions.length > 0;
}

private subscribeFilterOptions() {
  this.filteredOptions = this.formControl.valueChanges.pipe(
    startWith(''),
    map((value: string | Options) =>
    value && typeof value === 'string' ? this.options.filter((o) => 
 o.text.toLowerCase().includes(value.toLowerCase())) : 
this.options.slice()
   )
  );
}
removed(value: Options): void {
  this.onRemoved.emit(value);
  this.hasValue = this.selectedOptions.length > 0;
  }
 }

表单上的 Mat-chip-list 组件

<div class="col-md-12">
  <app-linq-chips
    label="Entities"
    placeholder="Add Entity..."
    [options]="entityOptions"
    [selectedOptions]="selectedEntities"
    [hint]="
      entityListHasDisabledOptions === true
        ? 'Please remove this contact from any roles for an entity prior to removing their 
     association to that entity.'
        : undefined
    "
    (onRemoved)="removeEntity($event)"
  >
  </app-linq-chips>
</div>

【问题讨论】:

    标签: javascript angular typescript


    【解决方案1】:

    您的变量hasValue 仅在选择或移除芯片时设置。当组件初始化时,它的值为 false,因为所选选项的数量为零。

    hasValue: boolean = this.selectedOptions.length > 0;
    

    required变量初始化为true,所以mat错误情况如下:

    <mat-error *ngIf="required === true && hasValue === false"> {{ label }} is 
     <strong>required</strong> </mat-error>
    

    将是真的,所以最初会显示错误。

    要解决此问题,请添加一个额外的布尔变量 isInitialized(或您想命名的任何名称),在 ngOnInit() 中将其设置为 false,然后在 ngAfterViewinit() 中将其设置为 true。

    更新您的mat-error 条件如下:

    <mat-error *ngIf="required === true && hasValue === false && isInitialized === true"> {{ label }} is 
     <strong>required</strong> </mat-error>
    

    尝试上述方法,它应该只在组件选择后进行错误检查。

    【讨论】:

    • 嗨@Andrew Halil,我更新了您建议的更改,并且在最初打开表单时仍会显示所需的消息。我还更新了我原来的帖子的鳕鱼,以显示您建议的更改。请检查以确保它看起来正确,如果它确实可以尝试其他操作,因为这不起作用。谢谢
    猜你喜欢
    • 2023-04-02
    • 1970-01-01
    • 2019-06-11
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    • 2022-11-09
    • 2017-09-25
    相关资源
    最近更新 更多