资讯专栏INFORMATION COLUMN

Angular 使用 ControlValueAccessor 创建自定义表单控件

AJie / 2548人阅读

摘要:在自定义表单控件,有时你想要的输入不是标准的文本输入选择或复选框。它获取一个函数,告诉其他表单指令和表单控件更新其值。与此类似,它专门为控件接收触摸事件时注册一个处理程序。

在 Angular 自定义表单控件,有时你想要的输入不是标准的文本输入、选择或复选框。通过实现ControlValueAccessor 接口并将组件注册为 NG_VALUE_ACCESSOR,您可以将自定义表单控件无缝地集成到模板驱动或响应表单中,就像它是本地表单一样!

ControlValueAccessor

ControlValueAccessor 是一个接口,充当Angular API 和 DOM 元素之间的桥梁

export interface ControlValueAccessor {
  writeValue(obj: any) : void
  registerOnChange(fn: any) : void
  registerOnTouched(fn: any) : void
}

writeValue(obj:any)是将表单模型中的值写入视图中。

writeValue(value: any): void {
   this._renderer.setProperty(this._elementRef.nativeElement, "value", value);
}

registerOnChange(fn:any)是一个方法,用于注册在视图中的某些内容发生更改时应调用的处理程序。它获取一个函数,告诉其他表单指令和表单控件更新其值。

registerOnChange(fn: (_: any) => void): void {
   this._onChange = fn;
}

registerOnTouched(fn:any)与registerOnChange()此类似,它专门为控件接收触摸事件时注册一个处理程序。

registerOnTouched(fn: any): void {
   this._onTouched = fn;
}

setDisabledState?(isDisabled: boolean): void; 是一个可选的方法,设置自定义表单的状态

setDisabledState(isDisabled: boolean): void {
   this._renderer.setProperty(this._elementRef.nativeElement, "disabled", isDisabled);
}
AbstractValueAccessor

我们可以把 ControlValueAccessor 中的方法写在一个抽象类中,不同的组件可以实现这个基类

export abstract class AbstractValueAccessor implements ControlValueAccessor {
  
  private _value: any = "";
  
  get value(): any {
    return this._value;
  }

  set value(v: any) {
    if (v !== this._value) {
      this._value = v;
      this.onChange(v);
      this.onTouched();
    }
  }

  writeValue(value: any) {
    this._value = value;
  }

  onChange = (_) => {};
  onTouched = () => {};

  registerOnChange(fn: (_: any) => void): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }
}

export function MakeProvider(type: any): { provide: any, useExisting: any, multi: boolean} {
  return { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => type), multi: true };
}
Example

自定义一个 list 控件,可以选择年级

在线预览

git仓库

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102501.html

相关文章

  • [译] 别再对 Angular 表单ControlValueAccessor 感到迷惑

    摘要:在里我们简单保存了对回调函数的引用,回调函数是由指令传入的译者注参考,只要每次组件值发生改变,就会触发这个回调函数。 原文链接:Never again be confused when implementing ControlValueAccessor in Angular forms showImg(https://segmentfault.com/img/bV7rR7?w=400...

    blastz 评论0 收藏0
  • @angular/forms 源码解析之双向绑定

    摘要:由于的属性提供了令牌,并且该令牌指向的对象就是,所以构造函数中注入的令牌包含的对象数组只有一个。这样的构造函数里就会包含一个对象,然后把这个传给对象,最后注册回调,这样以后值更新时就会运行。整个包的设计也是按照这种数据流形式,并不复杂。 我们知道,Angular 的 @angular/forms 包提供了 NgModel 指令,来实现双向绑定,即把一个 JS 变量(假设为 name)与...

    yangrd 评论0 收藏0
  • 构建一个定义 angular2 输入组件

    摘要:构建一个自定义输入组件今天我们来学习如何正确的构建和一个具有和同样作用,但同时也具有自己的逻辑的输入组件。值访问器在完成上面的一些步骤之后,我们的组件基本功能完成了,但是接下来还有最重要的一部分内容,那就是让我们的自定义组件获得值访问权限。 构建一个自定义 angular2 输入组件 今天我们来学习如何正确的构建和一个具有和 同样作用,但同时也具有自己的逻辑的输入组件。 在读这篇文章...

    CNZPH 评论0 收藏0
  • 构建一个定义 angular2 输入组件

    摘要:构建一个自定义输入组件今天我们来学习如何正确的构建和一个具有和同样作用,但同时也具有自己的逻辑的输入组件。值访问器在完成上面的一些步骤之后,我们的组件基本功能完成了,但是接下来还有最重要的一部分内容,那就是让我们的自定义组件获得值访问权限。 构建一个自定义 angular2 输入组件 今天我们来学习如何正确的构建和一个具有和 同样作用,但同时也具有自己的逻辑的输入组件。 在读这篇文章...

    pekonchan 评论0 收藏0
  • 使用Angular7开发一个Radio组件

    摘要:一准备工作以下简称已经跟之前版本大有不同。新建工程后,可方便创建简称是什么呢就是一个包的源码包。本文主要介绍本人写的一个组件。这是的一个可以方便原生和传值。本组件两个方法都重写了,因为值变更的时机自定义成了。 一、准备工作 Angular7(以下简称ng7),已经跟之前版本大有不同。新建工程后,可方便创建library(简称lib),lib是什么呢?就是一个npm包的源码包。npm作为...

    Tony_Zby 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<