如何创建自定义反应式表单元素?
How do I create a custom Reactive Form Element?
我在 Angular 中使用 Reactive Forms,我正在尝试创建一个自定义表单元素,以便我可以在我的表单中使用按钮。我正在尝试按照 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;
}
}
您需要实现 ControlValueAccessor 接口,为此,您需要实现以下方法:
interface ControlValueAccessor {
writeValue(obj: any): void
registerOnChange(fn: any): void
registerOnTouched(fn: any): void
setDisabledState(isDisabled: boolean)?: void
}
你可以看到我的示例实现对here。
当你的组件的值改变时,你必须调用你在 ts 文件中注册的 OnChange
方法。
你可以看我的调用例子here。
之后,您可以在表单中通过其标签选择器(在您的情况下为 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>
Here 您的代码是否有效。
我在 Angular 中使用 Reactive Forms,我正在尝试创建一个自定义表单元素,以便我可以在我的表单中使用按钮。我正在尝试按照 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;
}
}
您需要实现 ControlValueAccessor 接口,为此,您需要实现以下方法:
interface ControlValueAccessor {
writeValue(obj: any): void
registerOnChange(fn: any): void
registerOnTouched(fn: any): void
setDisabledState(isDisabled: boolean)?: void
}
你可以看到我的示例实现对here。
当你的组件的值改变时,你必须调用你在 ts 文件中注册的 OnChange
方法。
你可以看我的调用例子here。
之后,您可以在表单中通过其标签选择器(在您的情况下为 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>
Here 您的代码是否有效。