【发布时间】:2019-12-02 19:47:12
【问题描述】:
提供
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TestingComponent),
multi: true
}
注入的 NgControl
constructor(@Self() @Optional() public control: NgControl) {
this.control && (this.control.valueAccessor = this);
}
但这里还缺少什么?
虽然@Eliseo 的回答非常解释性,但还有一个补充......如果您想同时使用外部验证器和内部验证器,则必须相应地设置父 NgControl 验证器。此外,如果您想使用验证,您需要使用 ngDoCheck 生命周期钩子来处理 NgControl 触摸状态,因为下面是 最终的工作解决方案
@Component({
selector: 'app-testing',
templateUrl: 'testing.component.html'
})
export class TestingComponent implements ControlValueAccessor, DoCheck, AfterViewInit {
@Input()
public required: boolean;
@ViewChild('input', { read: NgControl })
private inputNgModel: NgModel;
public value: number;
public ngControlTouched: boolean;
constructor(@Optional() @Self() public ngControl: NgControl) {
if (this.ngControl != null) this.ngControl.valueAccessor = this;
}
ngDoCheck() {
if (this.ngControlTouched !== this.ngControl.touched) {
this.ngControlTouched = this.ngControl.touched;
}
}
ngAfterViewInit() {
// Setting ngModel validators to parent NgControl
this.ngControl.control.setValidators(this.inputNgModel.validator);
}
/**
* ControlValueAccessor Implementation
* Methods below
*/
writeValue(value: number): void {
this.value = value;
this.onChange(this.value);
}
onChange: (_: any) => void = (_: any) => {};
onTouched: () => void = () => {};
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
}
// Template
<input
#input="ngModel"
type="text"
class="form-control"
[class.is-invalid]="input.invalid && (input.dirty || input.touched || ngControlTouched)"
[(ngModel)]="value"
(ngModelChange)="onChange(value)"
(blur)="onTouched()"
[required]="required"
/>
// Usage
<app-testing [(ngModel)]="propertyDetails.whatThreeWords" name="testing" required></app-testing>
【问题讨论】:
-
有什么问题?
-
子组件必须通过父组件 NgForm 进行验证 (form.controls[key].markAsTouched();)。但是验证设置在一个孩子身上。感染 NgControl 不允许我将以下内容应用于孩子的输入 [class.is-invalid]="control.invalid && (control.dirty || control.touched)"
-
可以分享自定义控件类的代码吗?
标签: angular