Angular 控值訪問器(Control Value Accessor)

2024/10/25 0:03:11

本文主要是介绍Angular 控值訪問器(Control Value Accessor),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一个 ControlValueAccessor 工具是什么?

你知道 ControlValueAccessor 工具是什么吗?

控制值访问器接口(注释:ControlValueAccessor)是一个可以由你的组件实现的接口,使该组件能够像表单控件一样工作。

这意味着您可以像绑定 <input> 元素一样,将表单控件绑定到您的组件。

    <form [formGroup]="formGroup">  
      <your-cool-component [control]="formControl1" />  
      <input [control]="formControl2">  
    </form>

这是通过正确实现YourAwesomeComponent类中的ControlValueAccessor接口才实现的。上面的例子展示了反应式表单,同样的道理也适用于模板驱动表单。

在我撰写这段文字的时候,Angular 的文档目前还没有很清晰地说明如何在一个实际案例中使用_ControlValueAccessor_接口。每次我需要实现这个接口时,我都需要从网上找到的相关示例中重新理解它的构建模块的意义。这就是我在这里分享我的笔记的原因,希望帮助未来的自己和其他可能遇到同样问题的开发者们。

怎样才能使用ControlValueAccessor接口呢?

网上有许多教程通过实际案例展示如何使用ControlValueAccessor接口,并让用户自己理解接口各部分的含义。

我想在这里采用相反的做法:下面是一个模拟实现该接口的组件的例子,每个构建块都在注释中做了说明。

    import { Component, Optional, Self } from '@angular/core';  
    import { ControlValueAccessor, NgControl } from '@angular/forms';  

    @Component({  
      selector: 'your-awesome-component',  
      templateUrl: './your-awesome.component.html',  
    })  
    export class YourAwesomeComponent implements ControlValueAccessor {  
      // 自定义:你的组件将拥有某种内部状态。
      // 你决定它的类型以及它是如何运作的,
      // 根据你的使用情况。
      // 也可能不止一个字段,这完全取决于
      // 你的具体情形。
      protected internalComponentState;  

      // 控制:如果你需要跟踪绑定控制的禁用状态
      protected disabled = false;  

      // 这些是占位函数(实际的函数将由
      // 消费者设置 - 请参见下面的 registerOn* 方法)。
      // 我们需要在每次进行更改时都调用它们,
      // 这些更改必须反映给该组件的外部消费者,
      // 以指示表单控件何时被触摸
      // 和/或其值何时被更改。
      onChange: (value: string) => unknown = (_value: string) => {};  
      onTouched: () => unknown = () => {};  

      // 如果你需要从组件内部访问 FormControl 控制
      // 它将存在于 this.ngControl.control  
      constructor(@Optional() @Self() public ngControl: NgControl) {  
        if (this.ngControl) {  
          this.ngControl.valueAccessor = this;  
        }  
      }  

      // 允许消费者注册一个 onChange 函数  
      registerOnChange(fn: (value: string) => unknown): void {  
        // 通常这里就是这样,无需更改任何内容
        this.onChange = fn;  
      }  

      // 允许消费者注册一个 onTouched 函数  
      registerOnTouched(fn: () => unknown): void {  
        // 通常这里就是这样,无需更改任何内容
        this.onTouched = fn;  
      }  

      // 这是可选的,
      // 它允许你对表单控件的禁用状态作出反应
      setDisabledState(isDisabled: boolean): void {  
        // 我们将新的禁用状态绑定到
        // 内部(自定义)"disabled" 字段
        // 这是你通常要用这个函数做的事情
        // 但不是强制性的
        this.disabled = isDisabled;  
      }  

      // 每当表单控件的值发生变化时都会调用此方法
      writeValue(newValue: string): void {  
        // 你希望对 newValue 所做的取决于你的使用情况
        // 通常你想将它映射到你的 internalComponentState
        // 例如:
        this.internalComponentState = someProcessingFunction(newValue);  

        // 注意: 你可能希望只在 newValue 与
        // 当前的内部组件状态有所不同的情况下执行任何操作,
        // 以便优化性能
      }  

      // 自定义:从内部处理组件状态的变化
      onWhenTheUserPerformedSomeAction(): void {  
        // 在某个时刻,你想处理组件状态的变化
        // 并将它们反映到外部(与 this.writeValue() 相反)
        // 例如: 你的状态发生了变化
        this.internalComponentState = /*在这里做一些更改*/  
        const newValue = someMappingFunction(this.internalComponentState);  
        // 现在你想发出这些变化并更新表单的值:
        this.onChange(newValue);  
        // 这可能意味着你的表单控件现在也应该被视为已“被触碰”了。
        this.onTouched();  
      }  
    }
结论部分
  • ControlValueAccessor 是一个接口,Angular 组件可以通过实现该接口来绑定到表单控件;
  • 它就像一个桥梁,连接 Angular 表单 API 和自定义组件;
  • 表单控件的值和你自己的组件状态应该保持同步,并且在发生变化时相互更新,无论是通过外部的 writeValue() 调用还是内部的 onChange() 调用来更新状态。
谢谢.
  • 特别感谢 Kayzhe Tsar 的审阅。
简单英语 &#128640;

感谢你加入_简单英语_社区!在你离开之前,还有点事想说:

  • 记得给作者点赞关注他/她 ️&#128079;&#128079;️️
  • 关注我们: X | LinkedIn | YouTube | Discord | Newsletter
  • 看来看我们其他平台: CoFeed | Differ
  • 更多内容请在 PlainEnglish.io 查看


这篇关于Angular 控值訪問器(Control Value Accessor)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程