Как мне создать пользовательский реактивный элемент формы? - PullRequest
0 голосов
/ 14 января 2019

Я работаю с Reactive Forms в Angular и пытаюсь создать пользовательский элемент формы, чтобы я мог использовать кнопки с моей формой. Я пытаюсь следовать учебнику из Alligator.io , но не ясно, как интегрировать это в мой компонент. В настоящее время я получаю следующую ошибку.

ERROR Error: No value accessor for form control with name: 'coverage_for_domestic_partners'

Ниже мой код, любая помощь будет оценена.

// HTML

<div class="button-group" [formGroup]="group">
    <button
        *ngFor="let option of config.options"
        class="button button--toggle"
        [ngClass]='{"is-active": option.selected}'
        (click)="select($event, option)"
        [formControlName]="config.key">
        <div class="button-content">{{option.key}}</div>
    </button>
</div>

// Компонент

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

@Component({
 selector: 'z-toggle-group',
 templateUrl: './z-toggle-group.component.html',
 styleUrls: ['./z-toggle-group.component.scss'],
 providers: [
{
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => ZToggleGroupComponent),
  multi: true
}
  ]


 })
export class ZToggleGroupComponent implements OnInit, ControlValueAccessor {

@Input() config;
@Input() group: FormGroup;

@Input() disabled = false;
  @HostBinding('style.opacity')
  get opacity() {
    return this.disabled ? 0.25 : 1;
  }

clicked;

onChange = (rating: number) => {};
onTouched = () => {};

constructor() { }

ngOnInit() {
    // console.log('form', this.group)
      this.group.get(this.config.key).valueChanges.subscribe(value => {
        console.log('formValue', value);
    })
}

    writeValue(obj: any): void {
        throw new Error("Method not implemented.");
    }
    registerOnChange(fn: any): void {
        throw new Error("Method not implemented.");
    }
    registerOnTouched(fn: any): void {
        throw new Error("Method not implemented.");
    }
    setDisabledState?(isDisabled: boolean): void {
        throw new Error("Method not implemented.");
    }

select($event, option) {
    this.clicked = $event;
    this.group.get(this.config.key).patchValue(option.value, {onlySelf: true});

    this.config.options.forEach(option => {
        option.selected = false;
    })

    option.selected = true;
}

}

1 Ответ

0 голосов
/ 14 января 2019

Вам необходимо реализовать ControlValueAccessor интерфейс, для этого вам потребуется реализовать следующие методы:

interface ControlValueAccessor {
  writeValue(obj: any): void
  registerOnChange(fn: any): void
  registerOnTouched(fn: any): void
  setDisabledState(isDisabled: boolean)?: void
}

Вы можете увидеть мой пример реализации справа здесь .

Когда значение вашего компонента изменяется, вы должны вызвать метод OnChange, который вы зарегистрировали в своем файле ts.

Вы можете увидеть мой пример вызова здесь .

После этого вы можете использовать свой компонент с помощью его селектора тегов (в вашем случае z-toggle-group) внутри формы, и вы сможете использовать formControlName.

<div class="button-group" [formGroup]="group">
    <button
        *ngFor="let option of config.options"
        class="button button--toggle"
        [ngClass]='{"is-active": option.selected}'
        (click)="select($event, option)">

        <z-toggle-group [formControlName]="config.key"></z-toggle-group>

        <div class="button-content">{{option.key}}</div>
    </button>
</div>

Здесь ваш код работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...