如何创建自定义响应式表单元素?
Posted
技术标签:
【中文标题】如何创建自定义响应式表单元素?【英文标题】:How do I create a custom Reactive Form Element? 【发布时间】:2019-06-08 18:59:58 【问题描述】:我正在使用 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;
【问题讨论】:
writeValue(obj: any): void
registerOnChange(fn: any): void
registerOnTouched(fn: any): void
的实现在哪里?
抱歉,我一开始忘记复制粘贴了。我不确定如何将它们集成到我的功能中?
【参考方案1】:
你需要实现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 是你的代码工作。
【讨论】:
感谢您的回答,但这有点令人困惑。我想将以上是关于如何创建自定义响应式表单元素?的主要内容,如果未能解决你的问题,请参考以下文章