我正在实现 ControlValueAccessor 接口,以将组件转换为自定义表单控件。
我有一个封装了本地表单控件(例如输入:文本)的组件,并且可以直接在表单中完美地工作。
我有另一个组件封装了第一个组件,并且还实现了ControlValueAccessor接口。但是,当我尝试使用此组件时,它不会将值传递给第一个组件,只有在更改时才能获取它。
我不明白为什么它不起作用,因为我想象Angular应该将我的第一个组件识别为输入的表单控件,但是尽管它可以识别形式,但不能在另一个组件中识别它。
这是说明我问题的代码。
internal-control.component.ts
export const DEFAULT_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InternalControlComponent),
multi: true,
};
@Component({
selector: 'app-internal-control',
template: `<input type="text" ngDefaultControl>`,
providers: [ DEFAULT_VALUE_ACCESSOR ],
})
export class InternalControlComponent implements ControlValueAccessor {
@ViewChild(DefaultValueAccessor) private valueAccessor: DefaultValueAccessor;
writeValue(value: any): void {
this.valueAccessor.writeValue(value);
}
registerOnChange(fn: any): void {
this.valueAccessor.registerOnChange(fn);
}
registerOnTouched(fn: any): void {
this.valueAccessor.registerOnTouched(fn);
}
setDisabledState?(isDisabled: boolean): void {
this.valueAccessor.setDisabledState(isDisabled);
}
}
external-control.component.ts
export const DEFAULT_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ExternalControlComponent),
multi: true,
};
@Component({
selector: 'app-external-control',
template: `<app-internal-control type="text" ngDefaultControl></app-internal-control>`,
providers: [ DEFAULT_VALUE_ACCESSOR ],
})
export class ExternalControlComponent implements ControlValueAccessor {
@ViewChild(DefaultValueAccessor) private valueAccessor: DefaultValueAccessor;
writeValue(value: any): void {
this.valueAccessor.writeValue(value);
}
registerOnChange(fn: any): void {
this.valueAccessor.registerOnChange(fn);
}
registerOnTouched(fn: any): void {
this.valueAccessor.registerOnTouched(fn);
}
setDisabledState?(isDisabled: boolean): void {
this.valueAccessor.setDisabledState(isDisabled);
}
}
app.component.ts
@Component({
selector: 'app-root',
template:
`
<p>Internal control (it works)</p>
<app-internal-control [(ngModel)]="value" name="a"></app-internal-control>
<p>External control (doesn't work)</p>
<app-external-control [(ngModel)]="value" name="b"></app-external-control>
<p>Value:</p>
<span>"{{value}}"</span>
`,
})
export class AppComponent {
value = 'initial value';
}