У меня есть форма, созданная с помощью компонентов формы AngularMaterial. Я хочу отобразить ошибку, когда элемент управления формы имеет недопустимое состояние. Это сообщение должно рассчитываться каждый раз, когда изменяется статус или значение элемента управления формы. В качестве входных данных у меня будет элемент управления формы и объект ошибок.
Я подошел к этой проблеме, создав структурную директиву, но я не уверен, что это лучшее решение для нее, синтаксис заставляет меня усомниться в этом.
Директива:
@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
В настоящее время подход, который я использовал, работает, но я хотел бы узнать другие альтернативы или предложения по его улучшению.