Angular4 - No value accessor for form control

2019-01-07 09:36发布

I have a little prob with my form.

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

I try to add the formControlName but angular dont want to know anything and just saying :

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... but i dont know what to do.

I would like to bind my click to this formControl in order that when someone click on the entire card that push my 'type' into the formControl. Is it possible?

2条回答
We Are One
2楼-- · 2019-01-07 10:05

I think you should use formControlName="surveyType" on an input and not on a div

查看更多
Ridiculous、
3楼-- · 2019-01-07 10:10

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

查看更多
登录 后发表回答