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

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

问题描述

我有一个自定义元素:

<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

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

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