Angular4-没有用于表单控制的值访问器 [英] Angular4 - No value accessor for form control

查看:53
本文介绍了Angular4-没有用于表单控制的值访问器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义元素:

 <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>
 

当我尝试添加formControlName时,出现错误消息:

ERROR错误:名称为表单控件的无值访问器: 'surveyType'

我尝试添加ngDefaultControl失败. 似乎是因为没有输入/选择...而我不知道该怎么办.

我想将我的点击绑定到此formControl,以便当有人单击整个卡片时将我的类型"推入formControl.有可能吗?

解决方案

您只能在实现 ControlValueAccessor ,这意味着实现以下三个功能:

  • writeValue(告诉Angular如何将模型中的值写入视图)
  • registerOnChange(注册一个在视图更改时调用的处理程序函数)
  • registerOnTouched(注册一个在组件接收到触摸事件时要调用的处理程序,有助于了解组件是否已聚焦).

注册提供商

然后,您必须告诉Angular该指令是ControlValueAccessor(由于TypeScript编译为JavaScript时,它已从代码中剥离,因此接口不会将其剪切).您可以通过注册提供商来实现.

提供商应提供 NG_VALUE_ACCESSOR forwardRef .请注意,NG_VALUE_ACCESSOR应该是 multi提供者.

例如,如果您的自定义指令名为MyControlComponent,则应在传递给@Component装饰器的对象内的以下行中添加一些内容:

 providers: [
  { 
    provide: NG_VALUE_ACCESSOR,
    multi: true,
    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

这篇关于Angular4-没有用于表单控制的值访问器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆