如何改进此指令以显示带有错误的自定义错误

时间:2019-05-08 16:57:31

标签: angular angular-directive

我有一个使用AngularMaterial表单组件制作的表单。当表单控件具有无效状态时,我想显示一个错误。每当表单控件的状态或值更改时,都应计算该消息。作为输入,我将具有表单控件和errors对象。

我已经遇到了创建结构化指令的问题,但是我不确定这是最好的解决方案,语法使我对此感到怀疑。

指令:

@Directive({
  selector: '[appMensajeErrores]'
})
export class ErrorValidacionDirective implements OnInit, AfterViewInit, OnDestroy {
  control: AbstractControl;
  suscripcion: Subscription;
  errores: { [key: string]: string };

  @Input() set appMensajeErroresControl(c: AbstractControl) {
    this.control = c;
  }

  @Input() set appMensajeErrores(errores: { [key: string]: string }) {
    this.errores = errores;
  }

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef
  ) { }

  ngOnInit(): void {
  }

  ngAfterViewInit(): void {
    this.suscripcion = merge(this.control.valueChanges, this.control.statusChanges).subscribe(_ =>
      this.manejarEstadoValidez(), e => console.error(e)
    );
  }

  manejarEstadoValidez(): void {
    if (this.control.invalid) {
      const mensaje = this.generarMensaje(this.control, this.errores);
      this.viewContainer.clear();
      this.viewContainer.createEmbeddedView(this.templateRef, { $implicit: mensaje });
    } else {
      this.viewContainer.clear();
    }
  }

  generarMensaje(control: AbstractControl, errores: { [key: string]: string }): string {
    return Object.keys(control.errors)
      .reduce((acc, error) => errores[error] ? acc.concat(errores[error]) : acc, [])
      .join(',');
  }

  ngOnDestroy(): void {
    this.suscripcion.unsubscribe();
  }

}

已应用指令:

<mat-form-field floatLabel="always" >
        <mat-label>Magnitud</mat-label>
        <input matInput type="number" formControlName="magnitud">
        <mat-error *appMensajeErrores="{ required: 'Es requerido', max: 'Maximo 600' };let msg; control: form.get('parametros.magnitud')">{{msg}}</mat-error>
      </mat-form-field>

StackBlitz:https://stackblitz.com/edit/angular-material-q3wbeh

目前我采用的方法可行,但我想知道其他替代方法或改进它的建议。

1 个答案:

答案 0 :(得分:0)

我会使用'hasErrors'AbstractControl完成此操作。这样,我们在HTML内单独编写错误消息,并在FormControl的声明中定义触发器。此外,这也减少了对任何方法的需求。

// Declare the 'magnitud' control
magnitud: FormControl;

// Initialize the control with the 'required' and 'max' validators
ngOnInit(): void {
  this.magnitud = new FormControl('', [Validators.required, Validators.max(600)]);
}

HTML看起来像这样:

<mat-form-field floatLabel="always" >
  <mat-label>Magnitud</mat-label>
  <input matInput type="number" formControlName="magnitud">
  <mat-error *ngIf="magnitud.hasError('required')">Es requerido</mat-error>
  <mat-error *ngIf="magnitud.hasError('max')">Maximo 600</mat-error>
</mat-form-field>

希望这会有所帮助。