Angular4 - 表单控件没有值访问器 [英] Angular4 - No value accessor for form control
问题描述
我有一个自定义元素:
<div *ngFor="let 类型的surveyTypes"(点击)=onSelectType(类型)"[class.selected]="type === selectedType"><md-icon>{{ type.icon }}</md-icon><span>{{ type.description }}</span>
当我尝试添加 formControlName 时,我收到一条错误消息:
<块引用>错误错误:没有名称的表单控件的值访问器:'调查类型'
我尝试添加 ngDefaultControl
没有成功.似乎是因为没有输入/选择...我不知道该怎么办.
我想将我的点击绑定到这个 formControl,以便当有人点击整个卡片时,将我的类型"推入 formControl.可能吗?
您只能在实现 ControlValueAccessor
.
实现接口
所以,为了做你想做的事,你必须创建一个实现 ControlValueAccessor 的组件
,表示实现以下三个功能:
writeValue
(告诉 Angular 如何将值从模型写入视图)registerOnChange
(注册一个在视图改变时调用的处理函数)registerOnTouched
(注册一个在组件接收到触摸事件时要调用的处理程序,有助于了解组件是否已获得焦点).
注册提供商
然后,你必须告诉 Angular 这个指令是一个 ControlValueAccessor
(接口不会削减它,因为它在 TypeScript 被编译为 JavaScript 时从代码中剥离).您可以通过注册提供商来完成此操作.
提供商应提供 NG_VALUE_ACCESSOR
和 使用现有值.您还需要一个 forwardRef
这里.请注意,NG_VALUE_ACCESSOR
应该是 多供应商.
例如,如果您的自定义指令名为 MyControlComponent,您应该在传递给 @Component
装饰器的对象中添加以下几行内容:
提供者:[{提供:NG_VALUE_ACCESSOR,多:真实,useExisting: forwardRef(() => MyControlComponent),}]
用法
您的组件可以使用了.使用 模板驱动表单,ngModel
绑定现在将正常工作.
使用 反应式表单,您现在可以正确使用 formControlName
和表单控件将按预期运行.
资源
I have a custom element :
<div formControlName="surveyType">
<div *ngFor="let type of surveyTypes"
(click)="onSelectType(type)"
[class.selected]="type === selectedType">
<md-icon>{{ type.icon }}</md-icon>
<span>{{ type.description }}</span>
</div>
</div>
When I try to add the formControlName, I get an error message:
ERROR Error: No value accessor for form control with name: 'surveyType'
I tried to add ngDefaultControl
without success.
It seems it's because there is no input/select... and I dont know what to do.
I would like to bind my click to this formControl in order that when someone clicks on the entire card that would push my 'type' into the formControl. Is it possible?
You can use formControlName
only on directives which implement ControlValueAccessor
.
Implement the interface
So, in order to do what you want, you have to create a component which implements ControlValueAccessor
, which means implementing the following three functions:
writeValue
(tells Angular how to write value from model into view)registerOnChange
(registers a handler function that is called when the view changes)registerOnTouched
(registers a handler to be called when the component receives a touch event, useful for knowing if the component has been focused).
Register a provider
Then, you have to tell Angular that this directive is a ControlValueAccessor
(interface is not gonna cut it since it is stripped from the code when TypeScript is compiled to JavaScript). You do this by registering a provider.
The provider should provide NG_VALUE_ACCESSOR
and use an existing value. You'll also need a forwardRef
here. Note that NG_VALUE_ACCESSOR
should be a multi provider.
For example, if your custom directive is named MyControlComponent, you should add something along the following lines inside the object passed to @Component
decorator:
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => MyControlComponent),
}
]
Usage
Your component is ready to be used. With template-driven forms, ngModel
binding will now work properly.
With reactive forms, you can now properly use formControlName
and the form control will behave as expected.
Resources
- Custom Form Controls in Angular by Thoughtram
- Angular Custom Form Controls with Reactive Forms and NgModel by Cory Rylan
这篇关于Angular4 - 表单控件没有值访问器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!