Slip
Slip

Reputation: 949

How to use ControlValueAccessor?

I have a custom component InputField and SignupComponent with reactive form.

<ui-input-field formControlName="email" label="email"></ui-input-field>

When I do like this I get formControlName in ui-input-field, not in tag input. How to solve it?

I use ControlValueAccessor but don't understand how it work (method writeValue())

import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'ui-input-field',
  template: `
  <div class="group">
    <input  required [formControlName] />
    <span class="bar"></span>
    <label>{{label}}</label>
</div>
    `,
  styleUrls: ['input.component.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => InputFieldComponent),
      multi: true
    }]
})

export class InputFieldComponent implements OnInit, ControlValueAccessor {
  @Input() label: string;
  constructor() { }

  ngOnInit() {
  }    

  writeValue(value) {
    if (!value || typeof value !== 'string') {
      console.log('not value');
      return;
    }
  }    

  onChange: any = () => {
  }
  onTouched: any = () => {
  }

  registerOnChange(fn) {
    this.onChange(fn);
  }
  registerOnTouched(fn) {
    this.onTouched(fn);
  }
}

Upvotes: 0

Views: 716

Answers (1)

David Walschots
David Walschots

Reputation: 12640

There are numerous things incorrect in your implementation:

  1. The writeValue(obj: any): void function should be used to set the value of the input control in your component. You haven't implemented this correctly.
  2. The <input> element within your Component shouldn't have the formControlName attribute on it.
  3. registerOnChange and registerOnTouched are supplied with a function which you should call anytime your <input> has changed, or was touched. You haven't implemented this.

The documentation should provide more than enough details on how to proceed.

Upvotes: 1

Related Questions