小编典典

Angular4 - 表单控件没有值访问器

all

我有一个自定义元素:

<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 时,我收到一条错误消息:

错误错误:没有名称的表单控件的值访问器:’surveyType’

我尝试添加ngDefaultControl但没有成功。似乎是因为没有输入/选择......我不知道该怎么做。

我想将我的点击绑定到这个 formControl,以便当有人点击整个卡片时,会将我的“类型”推送到 formControl 中。可能吗?


阅读 198

收藏
2022-08-03

共1个答案

小编典典

formControlName只能在实现ControlValueAccessor.

实现接口

所以,为了做你想做的事,你必须创建一个实现的组件ControlValueAccessor,这意味着
实现以下三个功能

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

注册提供者

然后,你必须告诉 Angular 这个指令是一个ControlValueAccessor(接口不会删掉它,因为当 TypeScript 编译成
JavaScript 时它会从代码中剥离)。您可以通过 注册提供者 来做到这一点。

提供者应提供NG_VALUE_ACCESSOR使用现有值。你还需要一个forwardRef这里。注意NG_VALUE_ACCESSOR应该是一个多提供者

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

providers: [
  { 
    provide: NG_VALUE_ACCESSOR,
    multi: true,
    useExisting: forwardRef(() => MyControlComponent),
  }
]

用法

您的组件已准备好使用。使用模板驱动的表单ngModel绑定现在可以正常工作。

使用响应式表单,您现在可以正确使用formControlName并且表单控件将按预期运行。

资源

2022-08-03