We have a form component:
<label>
<h3>Type</h3>
<workout-type
formControlName="type"
></workout-type>
</label>
form = this.fb.group({
name: ['', Validators.required],
type: 'strength'
});
constructor(
private fb: FormBuilder
) {}
the 'type' FormControl will be a custom form element component which refers to 'workout-type' componet.
For the workout-type component:
import {ChangeDetectionStrategy, Component, forwardRef} from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; // Register the control value accessor export const TYPE_CONTROL_ACCESSOR = { provide: NG_VALUE_ACCESSOR, multi: true, useExisting: forwardRef(() => WorkoutTypeComponent) }; @Component({ selector: 'workout-type', providers: [TYPE_CONTROL_ACCESSOR], changeDetection: ChangeDetectionStrategy.OnPush, styleUrls: ['workout-type.component.scss'], template: ` <div class="workout-type"> <div *ngFor="let selector of selectors" [class.active]="selector === value" (click)="setSelected(selector)" class="workout-type__pane"> <img src="/img/{{selector}}.svg" alt="{{selector}}"> <p> {{selector}} </p> </div> </div> ` }) export class WorkoutTypeComponent implements ControlValueAccessor{ selectors = ['strength', 'endurance']; private onTouch: Function; private onModelChange: Function; private value: string; constructor() { } writeValue(value: string): void { this.value = value; } registerOnChange(fn: Function): void { this.onModelChange = fn; } registerOnTouched(fn: Function): void { this.onTouch = fn; } setSelected(value: string): void { this.value = value; this.onModelChange(value); this.onTouch(); } }