我正在努力理解ControlValueAccessor是如何精确地工作的。
我用两个不同的控制成分研究了它的行为:
因此,简而言之:
class FirstControlComponent implements ControlValueAccessor {
// ...
value:number = 10;
writeValue(value: number) {
this.value = value;
}
// ...
}
class SecondControlComponent implements ControlValueAccessor {
// ...
value:any = {};
writeValue(value: any) {
this.value = value;
}
// ...
}ControlValueAccessor接口只指定“setter”:writeValue,而没有指定“getter”。
因此,当我将控件绑定到SecondControlComponent时,如下所示:
this.form = this.builder.group({
controlName: this.builder.control(this.theObject) });随后在模板中:
<second-component ngControl='controlName'> <second-component>所有操作都很好,因为init上调用writeValue时引用了现有的theObject对象,因此控件修改了该对象的同一个实例(希望我很清楚)
但是:如果我对FirstControlComponent做了完全相同的事情,,因为值不是作为引用传递的(因为它是一个原语),而是因为 ControlValueAccessor没有提供'setter‘--在我的控件中的值和主机组件中的值没有保持同步.
这是否意味着我们必须传递对象而不是原语来实现ControlValueAccessor的自定义控件?我想不是,所以我想我一定是误会了..。:)
我用得对吗?
任何提示都欢迎!
谢谢!
发布于 2016-06-03 08:54:29
我不清楚您在这里试图做什么,但是ControlValueAccessor是一个您需要为元素注册的实体。就像这样:
const CUSTOM_VALUE_ACCESSOR = new Provider(
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => LabelsValueAccessor), multi: true});
@Directive({
(...)
providers: [CUSTOM_VALUE_ACCESSOR]
})
export class LabelsValueAccessor implements ControlValueAccessor {
(...)
}然后,它将接受部分值更新(来自组件和模板)。当您在输入的组件中设置一个值时(例如),writeValue方法将在您的值访问器中被调用。如果要从值访问器更新输入值,则需要利用Angular2注册的Angular2回调。
有关详细信息,请参阅本文(“NgModel兼容组件”一节):
发布于 2019-09-29 07:12:40
在父组件中,我希望输出像这个{someOtherControlName: any, controlName: number}那样的表单,所以子表单的输出必须是number.also (例如),formControl的parentform.patchValue({someOtherControlName: '', controlNmae: 3})值必须正确设置
@Component({
selector: 'parent',
template: `
<div [formGroup]="form">
<second-component [formControl]='form.controlName'> <second-component>
<div formControlName="someOtherControlName"></div>
export class ParentComponent {
parentForm = new FormGroup({
controlName: new FormControl(), <<<<<======important
someOtherControlName: new FormControl()
})
}在ControlValueAccessor中:
@Component({
selector: 'counter',
template: `
<div class="number-input" [formGroup]="form">
<input type="text" class="form-control text-center" formControlName="counter" />
</div>
`,
styleUrls: ['counter.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: CounterComponent,
multi: true,
},
],
})
export class CounterComponent implements ControlValueAccessor, OnDestroy, OnInit {
form = new FormGroup({
counter: new FormControl(0, Validators.required),
})
private onChange: (value: any) => void = value => {}
private onTouched: () => void = () => {}
myValue: number
private onDestroy$: Subject<void> = new Subject()
ngOnInit() {
this.form.valueChanges
.pipe(
tap(value => {
this.onChange(typeof value === 'number' ? value : value.counter) <<<< important
this.onTouched()
}),
takeUntil(this.onDestroy$)
)
.subscribe()
}
}
writeValue(value: number | { counter: number }) {
this.myValue = typeof value === 'number' ? value : value.counter
this.form.setValue({ counter: value > 0 ? value : 0 })
}
registerOnChange(fn: () => {}) {
this.onChange = fn
}
registerOnTouched(fn: () => {}) {
this.onTouched = fn
}
setDisabledState?(isDisabled: boolean): void {
// when the parent updates the
// state of the form control
if (isDisabled) {
this.form.disable()
} else {
this.form.enable()
}
}
ngOnDestroy(): void {
this.onDestroy$.next()
this.onDestroy$.complete()
}https://stackoverflow.com/questions/37609085
复制相似问题