typescript - ControlValueAccessor med felvalidering i Angular Material
Jag försöker tillämpa felvalideringsstil med ControlValueAccessor i en anpassad Material Input Textbox. Sedan jag började använda denna anpassade komponent visas inte längre alla röda kantvalideringsstatusar med formControlName/FormBuilders, för required, minlength, etc. Det fungerade nativt (direkt ur lådan) med Angular Material textbox, tills den anpassade kontrollen tillämpades.
Målet är att få en anpassad textruta att fungera med formulärvalidering. Detta visade sig naturligt med matInput-textrutan.
Uppdatering: Postat svar; dock osäker på om det är det mest effektiva, försöker få Saloo-svaret att fungera också (om någon kan posta stackbliz vore det bra), öppen för alla mer effektiva alternativ
Typescript:
import { Component, OnInit, Input, ViewChild, EventEmitter, Output, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-input-textbox',
templateUrl: './input-textbox.component.html',
styleUrls: ['./input-textbox.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputTextboxComponent),
multi: true
}
]
})
export class InputTextboxComponent implements OnInit, ControlValueAccessor {
@Input() MaxLength: string;
@Input() Value: string;
@Input() type: string;
@Input() Label: string;
@Input() PlaceHolder: string;
@Output() saveValue = new EventEmitter();
@Output() onStateChange = new EventEmitter();
disabled: boolean;
constructor() { }
ngOnInit() {
}
saveValueAction(e) {
this.saveValue.emit(e.target.value);
}
onChange(e) {
this.Value = e;
}
onTouched() {
this.onStateChange.emit();
}
writeValue(value: any) {
this.Value = value ? value : '';
}
registerOnChange(fn: any) { this.onChange = fn; }
registerOnTouched(fn: any) { this.onTouched = fn; }
setDisabledState(isDisabled) { this.disabled = isDisabled; }
}
HTML:
<div class="input-wrap">
<mat-form-field appearance="outline">
<mat-label>{{Label}}</mat-label>
<input matInput
[attr.maxlength] = "MaxLength"
[value]="Value ? Value : ''"
[placeholder]="PlaceHolder ? PlaceHolder : ''"
[type]="type ? type: 'text'"
(input)="onChange($event.target.value)"
>
</mat-form-field>
</div>
Försöker att integrera detta svar med den naturliga felstilen från Angular Material-textfält, ärva validering med hjälp av ControlValueAccessor i Angular
Svar #1
Jag hade samma problem. Jag försökte allt och kunde till slut lösa det med den här metoden:
Jag lade till den här lyssnaren på den anpassade komponenten. Du kan också göra det med 'blur'-händelsen.
@HostListener('focusout', ['$event.target'])
onFocusout() {
this.onTouched();
}
Och även anropa onTouched när man sätter något värde.
writeValue(value: any) {
this.onTouched();
this.Value = value ? value : '';
}
Svar #2
Jag använde din svar och länken du gav för att komma fram till denna lösning:
@Component({
selector: 'app-custom-input',
templateUrl: './custom-input.component.html',
styleUrls: ['./custom-input.component.css'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true
}]
})
export class CustomInputComponent implements OnInit, ControlValueAccessor {
...
_control: NgControl;
disabled: boolean;
constructor(@Inject(INJECTOR) private injector: Injector) {
}
ngOnInit() {
this._control = this.injector.get(NgControl);
}
...
custom-input.component.html
<div class="input-wrap">
<mat-form-field appearance="outline">
<mat-label>{{Label}}</mat-label>
<input matInput
[formControl]="_control.control" // <== this what makes it work
[attr.maxlength]="MaxLength"
[placeholder]="PlaceHolder ? PlaceHolder : ''"
[type]="type ? type: 'text'"
>
</mat-form-field>
</div>
Observera: Jag är inte bunden till MatInputs utdata (ja). FormControl-direktivet som skickar kontrollen till MatInput hanterar det åt oss.
gjorde ett exempel för dig
