加入收藏 | 设为首页 | 会员中心 | 我要投稿 好传媒网 (https://www.haochuanmei.com/)- 区块链、物联平台、物联安全、数据迁移、5G!
当前位置: 首页 > 教程 > 正文

Angular之ControlValueAccessor接口咋使用

发布时间:2023-08-02 11:30:31 所属栏目:教程 来源:互联网
导读:   这篇文章主要讲解了“Angular之ControlValueAccessor接口怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习&ldquo
  这篇文章主要讲解了“Angular之ControlValueAccessor接口怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Angular之ControlValueAccessor接口怎么使用”吧!
 
  ControlValueAccessor 是什么?
 
  简单来说ControlValueAccessor是一个接口,它被用于在 Angular 的 FormControl 实例和原生 DOM 元素之间创建一个桥梁。其使用方式和OnInit类似,需要程序员在自定义组件里面实现相应的方法。
 
  import {
 
  ControlValueAccessor,
 
  NG_VALUE_ACCESSOR
 
  } from '@angular/forms';
 
  @Component({
 
      selector: 'custom',
 
      templateUrl: './custom.component.html',
 
      styleUrls: ['./custom.component.less'],
 
      providers: [     
 
        {
 
          provide: NG_VALUE_ACCESSOR,
 
          useExisting: forwardRef(() => CustomComponent),
 
          multi: true     
 
        }   
 
      ]
 
  })
 
  export class CustomComponent implements ControlValueAccessor, OnInit, {…
 
  为什么需要使用 ControlValueAccessor
 
  有时,你可能需要创建自定义的表单元素,并希望它能和Angular的FormControl成功通信。这时你便需要ControlValueAccessor来实现这个目的。
 
  比如:
 
  this.myForm = new FormGroup({
 
      userName: new FormControl({value: '', disabled: false})
 
  });
 
  <form [formGroup]="myForm" (ngSubmit)="onSubmit()">
 
      <div class="form-group">
 
          <label>
 
              Name:
 
              <my-input formControlName="userName"></my-input>
 
          </label>
 
      </div>
 
      <div class="form-group">
 
          <button type="submit">Submit</button>
 
      </div>
 
  </form>
 
  深入理解
 
  ControlValueAccessor的使用方法在Angular官网和很多的文章中都有介绍,但是它具体是如何起作用的呢?
 
  Angular 需要一种通用机制来桥接原生/自定义表单控件和 formControl 指令,而这正是 ControlValueAccessor 干的事情。这个对象桥接原生表单控件和 formControl 指令,并同步两者的值。任何一个组件或指令都可以通过实现 ControlValueAccessor 接口并注册为 NG_VALUE_ACCESSOR,从而转变成 ControlValueAccessor 类型的对象。
 
  其实原生表单控件也拥有类似于ControlValueAccessor的接口,比如:当 Angular 在组件模板中中遇到 input 或 textarea DOM 原生控件时,就会使用DefaultValueAccessor 指令
 
  Accessor
 
  Form Element
 
  DefaultValueAccessor
 
  input,textarea
 
  CheckboxControlValueAccessor
 
  input[type=checkbox]
 
  NumberValueAccessor
 
  input[type=number]
 
  RadioControlValueAccessor
 
  input[type=radio]
 
  RangeValueAccessor
 
  input[type=range]
 
  SelectControlValueAccessor
 
  select
 
  SelectMultipleControlValueAccessor
 
  select[multiple]
 
  以上是Angular 为所有原生 DOM 表单元素创建的 Angular 表单控件,即内置ControlValueAccessor
 
  ControlValueAccessor 接口定义了四个方法:
 
  - writeValue(obj:any):将表单模型中的新值写入视图或DOM属性(如果需要)的方法,它将来自外部的数据写入到内部的数据模型。
 
  - registerOnChange(fn:any):一种注册处理程序的方法,当视图中的某些内容发生更改时应调用该处理程序。它具有一个告诉其他表单指令和表单控件以更新其值的函数。通常在 registerOnChange 中需要保存该事件触发函数,在数据改变的时候,可以通过调用事件触发函数通知外部数据变了,同时可以将修改后的数据作为参数传递出去。
 
  - registerOnTouched(fn: any):注册 onTouched 事件,基本同 registerOnChange ,只是该函数用于通知表单组件已经处于 touched 状态,改变绑定的 FormControl 的内部状态。
 
  - setDisabledState(isDisabled: boolean):当调用 FormControl 变更状态的 API 时得表单状态变为 Disabled 时调用 setDisabledState() 方法,以通知自定义表单组件当前表单的读写状态。
 
  formControl 指令使用 writeValue 方法设置原生表单控件的值;使用 registerOnChange 方法来注册由每次原生表单控件值更新时触发的回调函数,我们需要把更新的值传给这个回调函数,这样对应的 Angular 表单控件值也会更新;使用 registerOnTouched 方法来注册用户和控件交互时触发的回调。
 
  formControl会调用名为setUpControl的函数,ControlValueAccessor的实例valueAccessor会被作为参数传入这个函数中。在setUpControl中,ControlValueAccessor的四个方法会在交互时被调用,以完成formControl和元素之间的通信。
 
  拓展:
 
  在使用ControlValueAccessor时需要一同引入NG_VALUE_ACCESSOR,它是使用InjectionToken 创建的可在 Provider 中使用的 Token。我们在编写自己的项目时一般不需要用到InjectionToken,但是在一个框架或者第三方的插件中,它就变得十分有必要了。
 
  export const NG_VALUE_ACCESSOR =
 
      new InjectionToken<ReadonlyArray<ControlValueAccessor>>('NgValueAccessor');
 
  试想当我使用依赖注入的功能时,我需要将我创建的依赖注册进组件中。这时我就需要一个令牌,如果我使用一个字符串作为令牌就有可能会造成重复,相同的令牌会导致后面的覆盖前面的。所以需要一个Token作为一个唯一值来防止这种冲突。
 
  providers: [{ provide: TOKEN, useValue: … }]
 

(编辑:好传媒网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章