У меня есть простой Angular (v8.0) компонент, который просто содержит вход с required
набором атрибутов. У меня есть управляемая шаблоном форма, которая содержит этот компонент и привязывает его к начальному значению. Когда приложение запускается, статус ввода действителен, поскольку он привязан к начальному значению. Но форма неверно неверна. После внесения каких-либо изменений во входное значение состояние формы будет правильным и с тех пор остается правильным.
Я возвращаю статус проверки входных данных в моей реализации метода validate
и это, похоже, является источником проблемы. Это работает правильно, если я возвращаю объект, который я строю сам, основываясь на текущем значении элемента управления. Однако я бы предпочел этого избежать, потому что в будущем мне понадобятся другие состояния проверки, и я не хочу проверять их все вручную.
Я попытался добавить вызовы updateValueAndValidity
в различных местах кода, но это не имеет никакого эффекта.
Как сделать так, чтобы начальный статус проверки формы учитывал статус вложенного пользовательского компонента?
Вот код для компонента:
import { AfterViewInit, Component, ViewChild } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl, Validator, NgModel } from "@angular/forms";
@Component({
selector: "my-input",
template: '<input [(ngModel)]="value" required #model="ngModel" />',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: MyInputComponent,
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: MyInputComponent,
multi: true
}
]
})
export class MyInputComponent implements ControlValueAccessor, Validator {
onChange: any = () => {};
onTouch: any = () => {};
@ViewChild("model", { static: true }) model: NgModel;
private _value: string = "";
set value(x: string) {
if (this._value !== x) {
this._value = x;
this.onChange(x);
}
}
get value() {
return this._value;
}
writeValue(obj: any): void {
this.value = obj;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouch = fn;
}
validate(c: FormControl) {
return this.model.errors;
//return this.value ? null : { required: true }; // this works!
}
}
А вот код для внешней формы, которая содержит его:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
template: `
<form #frm="ngForm">
<my-input [(ngModel)]="myValue" name="myInput"></my-input>
</form>
`
})
export class AppComponent {
myValue: string = "hello";
}
Вот StackBlitz: https://stackblitz.com/edit/angular-lp3xpa . Добавьте или удалите символ для ввода, и статус формы изменится на действительный.
Всего 1 ответ
Это похоже на ту же проблему, что и этот вопрос , который предлагает обходной путь ручного запуска другой проверки из writeValue
с использованием setTimeout
. Кажется, это решает проблему.
В MyInputComonent
:
writeValue(obj: any): void {
this.value = obj;
setTimeout(() => { this.onChange(this.value); }, 0);
}
Смотрите здесь
Но это похоже на взлом.