在清除验证器时向组件发出事件



我已经创建了一个自定义输入组件。当存在所需的约束(在OnInit中计算(时,将显示其标签。

@Component({
selector: 'custom-input',
template: `<div *ngIf="isMandatory()">Mandatory</div><input/>`
})
export class CustomInput implements ControlValueAccessor, OnInit {
mandatory = false;
constructor(
@Self()
@Optional()
public ngControl: NgControl
) {
super(ngControl);
}
ngOnInit(): void {
this.mandatory  = this.isMandatory();
}
public isMandatory(): boolean {
let mandatory = false;
if (this.ngControl) {
const errors = new FormControl('', this.ngControl.control.validator, this.ngControl.control.asyncValidator).errors;
mandatory = errors?.required;
}
return mandatory;
}

writeValue(value: string): void {
this.value = value;
}
...

假设约束发生了变化。我想在输入变为可选时更新标签。

this.form = this.formBuilder.group({
custominput: new FormControl(null, Validators.required)
});
// remove required validator => I want to compute the 'mandatory' variable again
this.form.controls.customInput.clearValidators();
this.form.controls.customInput.updateValueAndValidity();

如何更新标签(在组件内发送事件(?我想避免订阅状态更改。

我发现的唯一技巧是:

writeValue(value: string): void {
this.value = value;
this.mandatory  = this.isMandatory();
}
... 
this.form = this.formBuilder.group({
customInput: new FormControl(null, Validators.required)
});

this.form.controls.customInput.clearValidators();
// In order to trigger writeValue function
this.form.controls.customInput.setValue(this.form.controls.customInput.value);
this.form.controls.customInput.updateValueAndValidity();

ngControl持有控制权,因此您可以使用

control.invalid ,control.dirty,control.touched, control.errors

更通用的方法是注入controlContainer

constructor(@Host() @SkipSelf() @Optional() private controlContainer: ControlContainer)
public ngOnInit() {
if (this.controlContainer) {
this.control = this.controlContainer.control.get(<control name>);
}
}

.html

<div [ngClass]="{ 'has-error': control && control.invalid && (control.dirty || control.touched) }"> 
<input
ngDefaultControl
id="{{ id }}"
placeholder="{{ placeholder }}"
[ngClass]="{
'ng-dirty ng-invalid': control && control.invalid && (control.dirty || control.touched)
}"
/>
<div
class="explain-error"
*ngIf="control && control.invalid && (control.dirty || control.touched)"
>
{{ control.errors | format-pipe }}
</div>
</div>

最新更新