angular自定义表单控件,解决错误No value accessor for form control with name: ‘xxx‘

目标:自定义表单控件(FormControl),增加灵活性和复用性。
场景:自定义组件作为表单控件,添加formControlName获取值。
报错:No value accessor for form control with name: ‘xxx’。
原因:将name绑定到了一个没有对应’value’的地方,或者说是找不到获取对应的’value’的通道。

解决方法1:添加ngDefaultControl元素

ngDefaultControl元素是基于DefaultValueAccessor指令的。
官方文档说明:

  1. DefaultValueAccessor是默认的ControlValueAccessor(值访问器),用于写入值,侦听输入元素的更改,该访问器由FormControlDirectiveFormControlNameNgModel指令使用。
  2. 默认情况下,此值访问器用于<input type=“text”><textarea>元素,但也可以将其用于具有类似行为且不需要特殊处理的自定义组件。为了将默认值访问器附加到自定义元素,请添加ngDefaultControl属性,如下所示。

总结: 报错是因为自定义组件没有对应的值访问器,需要自行额外添加。
例子:

<custom-input-component ngDefaultControl [(ngModel)]="value"></custom-input-component>

解决方法2:自定义组件实现ControlValueAccessor接口

说明: ControlValueAccessor接口是angular表单API和Dom元素的联系的通道。自定义组件实现该接口,为自定义元素提供了值访问器的同时,对值的获取和变化的处理也更加灵活。
方法: 该接口定义了四个方法,用来在表单模型与视图之间传递值和值的变化。

  1. writeValue(obj: any): void
    从表单API到Dom元素,传递值,即模型到视图的编程发生更改时,表单API会调用此方法写入视图。
    一般用法:当表单控件内容发生改变时(表单初始化赋值或者控件patchValue、setValue),表单API自动调用该方法,方法参数为改变后的值,因此我们需要在方法内部写好把值赋给Dom元素的代码。
    在这里插入图片描述

  2. registerOnChange(fn: any): void
    从Dom元素到表单API,传递变化,该方法注册一个回调函数,该控件的值在 UI 中更改时将调用该回调函数。
    一般用法:用户界面输入发生变化,调用回调函数,该回调函数需要我们在新写的值访问器组件里自行定义,然后在registerOnChange进行保存以注册。每次UI发生变化时,调用注册的函数,将发生的变化传递给表单。
    在这里插入图片描述

  3. registerOnTouched(fn: any): void,从组件到表单,注册了一个回调函数,获取视图中失去焦点(或者获取焦点)时,调用该方法。表单控件初始化时,表单formsAPI会调用该方法更新表单模型(失焦状态)。
    在这里插入图片描述

  4. setDisabledState(isDisabled: boolean)?: void,从表单到组件,当控件状态切换为disabled(或者从disabled切换)时,调用该方法,传入参数为控件当前的disabled状态值。
    在这里插入图片描述

例子:

@Component({
  selector: 'rh-foundation-data-selector',
  templateUrl: './foundation-data-infos.component.html',
  styleUrls: ['./foundation-data-infos.component.less'],
  providers: [
   	{
	   provide: NG_VALUE_ACCESSOR,
	   useExisting: forwardRef(() => RhFoundationDataInfosComponent),
	   multi: true
  	}
  ]
})
export class RhFoundationDataInfosComponent implements OnInit, ControlValueAccessor
  1. provide: NG_VALUE_ACCESSOR,用于为表单控件提供ControlValueAccessor的Token。
  2. useExisting: forwardRef(() => RhFoundationDataInfosComponent),forwardRef让我们在使用构造注入时,使用尚未定义的依赖对象类型。
  3. multi: true,可能存在多个表单自定义控件,都注册到了NG_VALUE_ACCESSOR的Token上面,因此设置为true。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值