包角材料输入的组件不显示错误样式

一句话

我想将角材料的matInput封装在组件中,以便在应用程序的其他位置重用它,因为我需要管理其内部状态,以将输入类型从文本更改为密码,反之亦然。

我设法通过实现ControlValueAccessor来做到这一点,但是没有显示验证错误的样式。

密码字段部分:

export class PasswordFieldComponent
  implements OnInit, ControlValueAccessor {

  @ViewChild(DefaultValueAccessor) private valueAccessor: DefaultValueAccessor;

  @Input() customClass: string;
  @Input() customPlaceholder: string;
  @Input() required = true;

  hide = true;

  constructor() { }

  ngOnInit() {
  }

  private propagateChange = (_: any) => { };

  private onChange(event) {
    this.propagateChange(event.target.value);
  }

  private onTouch() { }

  registerOnChange(fn: any): void {
    this.valueAccessor.registerOnChange(fn);
  }

  registerOnTouched(fn: any): void {
    this.valueAccessor.registerOnTouched(fn);
  }

  setDisabledState(isDisabled: boolean): void {
    this.valueAccessor.setDisabledState(isDisabled);
  }

  writeValue(value: any): void {
    this.valueAccessor.writeValue(value);
  }

}

密码字段模板:

<mat-form-field class="full-width {{ customClass }}">

  <input
    matInput
    ngDefaultControl
    placeholder="{{ customPlaceholder }}"
    [required]="required"
    [type]="hide ? 'password' : 'text'"
    (input)="onChange($event)">

  <button mat-icon-button matSuffix (click)="hide = !hide" [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide">
    <mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
  </button>

</mat-form-field>

在此处输入图片说明

埃利索

The code from my comments is make the "most simple custom form control that has a material input inside". The idea is create custom ErrorStateMatcher that ask about the control itself. So, out inner material input show errors not when it was invalid else when our custom control was invalid

This ErrorStateMatcher need the know about our control, so we are going to create a constructor to inject this control (I inject in constructor another object "errors" to alow make "invalid" the material input)

class CustomFieldErrorMatcher implements ErrorStateMatcher {
  constructor(private customControl: FormControl,private errors:any) { }

  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return this.customControl && this.customControl.touched &&(this.customControl.invalid || this.errors);
  }
}

The .html is like

<mat-form-field>

    <input #input="ngModel" [ngModel]="value" (ngModelChange)="value=$event;onChange($event)"
    matInput
    [errorStateMatcher]="errorMatcher()"
    [placeholder]="placeholder"
    [type]="hide ? 'password' : 'text'"
    (blur)="onTouched()"
    >
    <button mat-icon-button matSuffix (click)="hide = !hide" [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide">
    <mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
  </button>
    <mat-error *ngIf="control?.errors?.required">
        Please enter a {{placeholder}}
    </mat-error>
    <mat-error *ngIf="errors?.errorMatch">
        Must match
    </mat-error>

</mat-form-field>

The most important part is this

[errorStateMatcher]="errorMatcher()"

看到使用[ngModel]和(ngModel),(模糊)将自定义formControl标记为“ touched”。我添加了一个mat-error * ngIf =“ errors?.errorMatch。这是一个@Input()获取Form的error值的代码。这是因为如果两个字段“ password”和“ repeatpassword”使我们拥有一个自定义错误的FormGroup, “ 不匹配。

我们的自定义表单控件就像

export class CustomSelectComponent implements AfterViewInit, ControlValueAccessor {

  control: FormControl
  onChange: any = () => { };
  onTouched: any = () => { };

  value: any;
  @Input() disabled: boolean;
  @Input() placeholder = '';
  @Input() errors:any=null;

  errorMatcher() {
    return new CustomFieldErrorMatcher(this.control,this.errors)
  }
  constructor(public injector: Injector) {
  }

  ngAfterViewInit(): void {
    const ngControl: NgControl = this.injector.get(NgControl, null);
    if (ngControl) {
      setTimeout(() => {
        this.control = ngControl.control as FormControl;
      })
    }
  }

查看如何在ngAfterViewInit中获取ngControl,如何errorMatcher()返回新的CustomFieldErrorMatcher以及如何传递“ control”和“ errors”的值。

好吧,我们的app.component就像

  ngOnInit() {
    this.myForm = new FormGroup(
      {
        password: new FormControl("", Validators.required),
        repeatpassword: new FormControl("", Validators.required)
      },
      this.matchControls("password", "repeatpassword")
    );
  }

  matchControls(field1, field2) {
    return (group: FormGroup) => {
      const control1 = group.get(field1);
      const control2 = group.get(field2);
      return control1 && control2 &&
        control1.value && control2.value &&
        control1.value != control2.value
        ? { errorMatch: "must match" }: null;
    };
  }

app.component的.html是

<form [formGroup]="myForm" autocomplete="off">
    <app-custom-input placeholder="Password" formControlName="password" >
    </app-custom-input>
    <app-custom-input placeholder="Repeat password" formControlName="repeatpassword" [errors]="myForm.errors?.errorMatch?myForm.errors:null" >
    </app-custom-input>
</form>

stackblitz

在自定义组件上添加了此侦听器。您也可以将其“模糊”事件。

https://stackoverflow.com/a/59086644/12425844

@HostListener('focusout', ['$event.target'])
  onFocusout() {
    this.onTouched();
  }
And also calling onTouched when setting any value.

 writeValue(value: any) {
    this.onTouched();
    this.Value = value ? value : '';
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

角材料:组件的样式不正确

来自分类Dev

角材料表不显示任何数据

来自分类Dev

角材料输入验证错误消息

来自分类Dev

每行角材料输入

来自分类Dev

角材料不会应用样式

来自分类Dev

角材料样式未加载

来自分类Dev

在不显示的情况下更改输入样式:无

来自分类Dev

ASP.NET 中密码输入的 CSS 样式不显示

来自分类Dev

角材料表不显示数据,直到我单击分页链接

来自分类Dev

样式化的组件语义工具包(表格输入)

来自分类Dev

样式不显示

来自分类Dev

如何样式角材料选择

来自分类Dev

JPanel不显示组件

来自分类Dev

ReactJS组件不显示

来自分类Dev

ReactJS组件不显示

来自分类Dev

组件使用的角材料意图和色相

来自分类Dev

从材料UI组件中提取样式

来自分类Dev

设置材料UI React组件的样式

来自分类Dev

角材料如何使按钮与输入的高度相同

来自分类Dev

角材料Md工具栏输入

来自分类Dev

由于输入数据帧错误,条形图不显示

来自分类Dev

角谷歌地图不显示

来自分类Dev

角模态模板不显示

来自分类Dev

输入文本子组件在从父组件键入传递onChange函数时不显示任何文本

来自分类Dev

材料 2 - 自动完成不显示选项

来自分类Dev

Vue-使用类样式绑定在应用程序中不显示组件CSS类

来自分类Dev

角材料Sidenav呈现但未显示

来自分类Dev

Eclipse在软件包上显示错误,但在此软件包内Eclipse不显示错误

来自分类Dev

角材料-带有主题的错误