首页
/ Angular @angular/forms 公共 API 全解析:从 goldens/public-api/forms/index.api.md 读懂表单包完整接口面

Angular @angular/forms 公共 API 全解析:从 goldens/public-api/forms/index.api.md 读懂表单包完整接口面

2026-09-07 15:03:29作者:吴年前Myrtle

本文以 Angular 仓库中 @angular/forms 的公共 API 快照文件 goldens/public-api/forms/index.api.md 为主体,系统讲解该 API 报告文件的生成与维护机制,并逐层剖析它记录的整套表单公共接口:模型层(AbstractControl/FormControl/FormGroup/FormArray)、FormBuilder 家族、验证器 API、模板驱动与响应式两套指令体系、ControlValueAccessor 值访问器与注入令牌、以及表单事件系统,帮助你在阅读源码、二次封装或升级依赖时精确掌握 @angular/forms 的公共契约。

API 报告文件是什么:生成器、快照与守护测试

index.api.md 文件头部明确标注了两条元信息:

API Report File for "@angular/forms" —— Do not edit this file. It is a report generated by API Extractor.

即它是由 API Extractor 工具从 @angular/forms.d.ts 类型定义中提取、自动生成的公共 API 报告(API golden)。报告中每一条导出都带有 API-Extracter 的文档化层级标记(如 // @public// @public (undocumented)),完整列出了 AbstractControlFormControlFormGroupFormArrayFormBuilder、各表单指令、Validators 等全部公共成员的精确签名。它的价值在于:

  • 契约快照:它是 @angular/forms 对外发布接口的"权威清单",任何新增、删除或重命名公共成员都会导致该文件内容变化;
  • 变更门禁:仓库将其作为 Bazel 黄金文件测试(golden test)的一部分,在 CI 中比对实际 API 与快照是否一致,从而防止公共 API 被意外破坏。

快照如何生成与更新

维护流程在 goldens/README.md 中有明确说明:goldens/public-api/ 目录保存所有发布到 NPM 的包的公共 API 快照,并在所有 PR 和提交中作为 Bazel 测试运行。两条核心命令(定义于根 package.json):

pnpm public-api:check    # 等价于 node goldens/public-api/manage.js test
pnpm public-api:update   # 等价于 node goldens/public-api/manage.js accept

编排脚本 goldens/public-api/manage.js 的工作方式是:先通过 Bazel 查询出所有带 api_guard 标签的 js_test 目标,再对 test 模式逐个运行测试、对 accept 模式逐个运行对应的 <target>.accept 目标重新生成快照。

落到 @angular/forms 包,packages/forms/BUILD.bazel 中定义了两个守护目标:

api_golden_test_npm_package(
    name = "forms_api",
    data = [":npm_package", "//goldens:public-api"],
    golden_dir = "goldens/public-api/forms",
    npm_package = "packages/forms/npm_package",
)

api_golden_test(
    name = "forms_errors",
    entry_point = "src/errors.d.ts",
    golden = "goldens/public-api/forms/errors.api.md",
)

前者对 npm 打包产物生成整个 goldens/public-api/forms/ 目录下的快照(即本文件所在目录),后者单独守护错误模块 src/errors.d.ts 的 API。而从源码结构看,公共入口由 packages/forms/public_api.ts 统一收敛——它只重导出 ./src/forms,注释要求"只 reexport src 文件夹内容",这正是 API Extractor 提取的边界。

模型层:AbstractControl 及其四个基本构建块

报告中最长的段落属于模型层(约 25–321 行),它定义了所有表单控件的公共行为契约。packages/forms/PACKAGE.md 将该包定位为实现"指令与 provider 集合,用于在构建表单时与原生 DOM 元素通信以捕获用户输入",而模型层就是这套契约的数据核心。

AbstractControl:状态、事件与标记位

AbstractControl 是抽象基类(报告中声明为 @public),其完整签名体现了三层设计:值、状态、事件。

export abstract class AbstractControl<
  TValue = any,
  TRawValue extends TValue = TValue,
  TValueWithOptionalControlStates = any
> {
  constructor(validators: ValidatorFn | ValidatorFn[] | null,
              asyncValidators: AsyncValidatorFn | AsyncValidatorFn[] | null);

  // 状态标志
  get valid(): boolean;      get invalid(): boolean;
  get pending(): boolean;    get disabled(): boolean;   get enabled(): boolean;
  get dirty(): boolean;      get pristine(): boolean;
  get touched(): boolean;   get untouched(): boolean;
  get status(): FormControlStatus;

  // 错误访问
  readonly errors: ValidationErrors | null;
  getError(errorCode: string, path?: Array<string | number> | string): any;
  hasError(errorCode: string, path?: Array<string | number> | string): boolean;
  setErrors(errors: ValidationErrors | null, opts?: { emitEvent?: boolean }): void;

  // 值操作
  readonly value: TValue;
  readonly valueChanges: Observable<TValue>;
  readonly statusChanges: Observable<FormControlStatus>;
  getRawValue(): any;
  abstract patchValue(value: TValue, options?: Object): void;
  abstract setValue(value: TRawValue, options?: Object): void;
  abstract reset(value?: TValueWithOptionalControlStates, options?: Object): void;

  // 树形关系
  get parent(): FormGroup | FormArray | null;
  get root(): AbstractControl;
  setParent(parent: FormGroup | FormArray | null): void;
  get<P extends string | readonly (string | number)[]>(path: P):
      AbstractControlGetProperty<TRawValue, P>> | null;

  // 状态标记与验证器管理(均支持 { onlySelf?, emitEvent? })
  markAsTouched(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  markAsDirty(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  markAsPending(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  ...
  addValidators(validators: ValidatorFn | ValidatorFn[]): void;
  addAsyncValidators(validators: AsyncValidatorFn | AsyncValidatorFn[]): void;
  hasValidator(validator: ValidatorFn): boolean;
  hasAsyncValidator(validator: AsyncValidatorFn): boolean;
  updateValueAndValidity(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void;

  // 更新时机与事件流
  get updateOn(): FormHooks;
  readonly events: Observable<ControlEvent<TValue>>;
}

几个值得注意的 API 设计点:

  • 状态机FormControlStatus 在报告中定义为联合类型 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED',与 status getter、statusChanges Observable 配套;
  • onlySelf 语义markAs*updateValueAndValiditysetValue 等普遍接受 { onlySelf?: boolean; emitEvent?: boolean },用于控制操作是否向父/子控件级联、是否发射事件——这是响应式表单中精细控制状态传播的关键开关;
  • updateOn: FormHooks:报告将 FormHooks 具体化为 'change' | 'blur' | 'submit'(见 AbstractControlOptions),实现于 packages/forms/src/model/abstract_model.ts
  • events 通道Observable<ControlEvent<TValue>> 是一个统一事件流,后续"事件系统"小节的 ValueChangeEventStatusChangeEvent 等都会流经它;
  • 泛型 get(path):用模板字面量式的路径类型推断子控件的值类型,AbstractControl<ɵGetProperty<TRawValue, P>> 表明点路径取值时类型会被精确推导。

FormControl:单个输入框的模型

FormControl<TValue> 是接口式定义(继承 AbstractControl<TValue>),在报告中暴露了比基类更具体的能力:

export interface FormControl<TValue = any> extends AbstractControl<TValue> {
  defaultValue: TValue;
  getRawValue(): TValue;
  registerOnChange(fn: Function): void;
  registerOnDisabledChange(fn: (isDisabled: boolean) => void): void;
  patchValue(value: TValue, options?: {
    onlySelf?: boolean; emitEvent?: boolean;
    emitModelToViewChange?: boolean; emitViewToModelChange?: boolean;
  }): void;
  setValue(value: TValue, options?: {
    onlySelf?: boolean; emitEvent?: boolean;
    emitModelToViewChange?: boolean; emitViewToModelChange?: boolean;
  }): void;
  reset(formState?: TValue | FormControlState<TValue>, options?: {
    onlySelf?: boolean; emitEvent?: boolean; overwriteDefaultValue?: boolean;
  }): void;
}

// @public (undocumented)
export const FormControl: ɵFormControlCtor;

配套的类型定义(实现见 packages/forms/src/model/form_control.ts):

/** 装箱值:value + disabled 两键必填 */
export interface FormControlState<T> { value: T; disabled: boolean; }

export interface FormControlOptions extends AbstractControlOptions {
  nonNullable?: boolean;              // 初始值即默认值,reset 后不回退为 null
  /** @deprecated Use `nonNullable` instead. */
  initialValueIsDefault?: boolean;
}

export interface AbstractControlOptions {
  validators?: ValidatorFn | ValidatorFn[] | null;
  asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null;
  updateOn?: 'change' | 'blur' | 'submit';
}

从报告与源码可以确认几个语义:nonNullable: true 让初始值同时成为默认值,reset() 不带参数时回落到该值而非 null;旧的 initialValueIsDefault 选项已标记 @deprecated,报告将其同时保留以维持向后兼容。ɵFormControlCtor 这个"值导出"(报告中标注 @public (undocumented))是编译器内部实现构造函数,对外部使用者来说 new FormControl(...) 的调用形态不变。FormControlState<T> 支持用 { value, disabled } 形式同时携带初始值与禁用状态初始化控件。

FormGroup 与 FormRecord:具名控件集合

export class FormGroup<TControl extends { [K in keyof TControl]: AbstractControl<any> } = any>
    extends AbstractControl<...> {
  constructor(controls: TControl,
              validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
              asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
  addControl(name: string, control: AbstractControl, options?: { emitEvent?: boolean }): void;
  contains(controlName: string): boolean;
  controls: TControl;                       // 具名子控件映射
  getRawValue(): ...;
  patchValue(value: ..., options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  registerControl(name: string, control): ...;
  removeControl(name: string, options?: { emitEvent?: boolean }): void;
  reset(value?: ..., options?: { onlySelf?; emitEvent?; overwriteDefaultValue? }): void;
  setControl(name: string, control: AbstractControl, options?: { emitEvent?: boolean }): void;
  setValue(value: ..., options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
}

FormGroup 的方法重载对泛型具名 key(K extends string & keyof TControl)与字符串 key 分别给出精确类型,removeControl 对可选 key 有专门的重载(ɵOptionalKeys<TControl> & S),从源码结构看这是为了在"运行时删除可选字段"时保持类型安全。

FormRecord 则是字符串键的 FormGroup 特化,报告中定义为 class FormRecord<TControl> extends FormGroup<{ [key: string]: TControl }> {},并提供同名接口形式描述其成员方法,适用于控件数量动态、键名不固定的场景。

FormArray:顺序控件集合

export class FormArray<TControl extends AbstractControl<any> = any>
    extends AbstractControl<...> {
  constructor(controls: Array<TControl>,
              validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
              asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
  at(index: number): TControl;
  clear(options?: { emitEvent?: boolean }): void;
  controls: Array<TControl>;
  getRawValue(): ...;
  insert(index: number, control: TControl, options?: { emitEvent?: boolean }): void;
  get length(): number;
  patchValue(value: ..., options?: { onlySelf?; emitEvent? }): void;
  push(control: TControl | Array<TControl>, options?: { emitEvent?: boolean }): void;
  removeAt(index: number, options?: { emitEvent?: boolean }): void;
  reset(value?: ..., options?: { onlySelf?; emitEvent?; overwriteDefaultValue? }): void;
  setControl(index: number, control: TControl, options?: { emitEvent?: boolean }): void;
  setValue(value: ..., options?: { onlySelf?; emitEvent? }): void;
}

FormArray 提供 push/insert/removeAt/setControl/at/clear 的完整列表操作,且几乎所有变更方法都接受 emitEvent 选项,与 FormGroupsetControl/addControl/removeControl 对应,共同构成动态表单的数据基础。

FormBuilder 家族:group / control / array / record 与类型变体

报告中的 FormBuilder@Injectable(可见 static ɵprov 注入声明),提供四个工厂方法与一个非空变体:

export class FormBuilder {
  control(formState: T | FormControlState<T>,
           validatorOrOpts?: ValidatorFn | ValidatorFn[] | FormControlOptions | null,
           asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): FormControl<T | null>;
  // 非空重载
  control<T>(formState: T | FormControlState<T>,
             opts: FormControlOptions & { nonNullable: true }): FormControl<T>;

  group<T extends {}>(controls: T, options?: AbstractControlOptions | null): FormGroup<...>;
  array<T>(controls: Array<T>, validatorOrOpts?: ..., asyncValidator?: ...): FormArray<...>;
  record<T>(controls: { [key: string]: T }, options?: AbstractControlOptions | null): FormRecord<...>;

  get nonNullable(): NonNullableFormBuilder;
}

要点:

  • 默认值类型包含 nullFormBuilder.control 的通用重载返回 FormControl<T | null>,这与 FormControl 文档注释一致——"控件被 reset 后会变成 null";
  • nonNullable 双通道:既可以在 control() 单控件上通过 { nonNullable: true } 重载得到 FormControl<T>,也可以通过 this.fb.nonNullable.group(...) 得到 NonNullableFormBuilder,其 group/array/control/record 全部返回非空值类型(ɵNonNullableFormControls<T>ɵElement<T, never> 等);
  • group 的第二个参数弃用重载:报告保留了 group(controls: {[key: string]: any}, options: {[key: string]: any}) 并标注 @deprecated,历史上曾用于"逐控件选项",现已由 AbstractControlOptions 取代;
  • Untyped 变体UntypedFormBuilder(继承 FormBuildergroup/array/control 返回 UntypedFormGroup/UntypedFormArray/UntypedFormControl)、UntypedFormGroup = FormGroup<any>UntypedFormControl = FormControl<any>UntypedFormArray = FormArray<any>,均带 ɵ* 实现构造函数导出,服务于未迁移到类型化 API 的旧代码;
  • 辅助配置类型 ControlConfig<T> = [T | FormControlState<T>, (ValidatorFn | ValidatorFn[])?, (AsyncValidatorFn | AsyncValidatorFn[])?] 是位置元组形式的控件配置。

FormBuilder 的实现位于 packages/forms/src/form_builder.ts

验证 API:静态 Validators 与内置验证器指令

报告中的 Validators 类提供纯函数式验证器(实现见 packages/forms/src/validators.ts):

export class Validators {
  static compose(validators: (ValidatorFn | null | undefined)[]): ValidatorFn | null;
  static composeAsync(validators: (AsyncValidatorFn | null)[]): AsyncValidatorFn | null;
  static email(control: AbstractControl): ValidationErrors | null;
  static max(max: number): ValidatorFn;
  static maxLength(maxLength: number): ValidatorFn;
  static min(min: number): ValidatorFn;
  static minLength(minLength: number): ValidatorFn;
  static nullValidator(control: AbstractControl): ValidationErrors | null;
  static pattern(pattern: string | RegExp): ValidatorFn;
  static required(control: AbstractControl): ValidationErrors | null;
  static requiredTrue(control: AbstractControl): ValidationErrors | null;
}

export type ValidationErrors = { [key: string]: any };

export interface ValidatorFn { (control: AbstractControl): ValidationErrors | null; }
export interface AsyncValidatorFn {
  (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
}
export interface Validator {
  registerOnValidatorChange?(fn: () => void): void;
  validate(control: AbstractControl): ValidationErrors | null;
}
export interface AsyncValidator extends Validator {
  validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
}

Validator(类方法式)与 ValidatorFn(函数式)双形态并存,AbstractControladdValidators/setValidators/hasValidator 等方法同时接受两者,这是自定义验证器可以以"可注入类"形式复用的原因。

另一组是绑定到模板属性的内置验证器指令,它们的 selector 都同时匹配 [formControlName][formControl][ngModel] 三种场景(见报告 635–931 行):

指令 报告中的 selector 核心 绑定属性
RequiredValidator :not([type=checkbox])[required] required
CheckboxRequiredValidator input[type=checkbox][required] —(复用 required 语义)
EmailValidator [email] email
MinLengthValidator / MaxLengthValidator [minlength] / [maxlength] minlength / maxlength
MinValidator / MaxValidator input[type=number][min] / [max] min / max
PatternValidator [pattern] pattern: string | RegExp

这些指令均继承 AbstractValidatorDirective,通过 NG_VALIDATORS 多令牌注入到控件的验证管线中(见下文令牌小节)。

指令体系:模板驱动 vs 响应式两套 selector

报告记录了表单与 DOM 通信的全部指令契约。两类体系的 selector 设计(来自各指令的 ɵdir 声明)值得精确记忆:

响应式表单指令(ReactiveFormsModule 提供)

  • FormGroupDirective:selector [formGroup],导出 form: FormGroup 输入与 ngSubmit 输出;
  • FormControlDirective:selector [formControl],输入别名 formControldisabledisDisabled)、ngModel(已弃用的 model);
  • FormControlName:selector [formControlName],需要 name 与父级 ControlContainer
  • FormArrayDirective:selector [formArray]
  • FormArrayName / FormGroupName:selector [formArrayName] / [formGroupName],用于嵌套分组。

FormGroupDirective 等继承自 AbstractFormDirective,其公共契约(报告 144–181 行)包含:

abstract class AbstractFormDirective extends ControlContainer
    implements Form, OnChanges, OnDestroy {
  directives: FormControlName[];
  addControl(dir: FormControlName): FormControl;
  addFormGroup(dir: FormGroupName): void;
  addFormArray(dir: FormArrayName): void;
  getControl(dir: FormControlName): FormControl;
  getFormGroup(dir: FormGroupName): FormGroup;
  getFormArray(dir: FormArrayName): FormArray;
  removeControl(dir: FormControlName): void;
  ...
  resetForm(value?: any, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  get submitted(): boolean;
  updateModel(dir: FormControlName, value: any): void;
  onSubmit($event: Event): boolean;
}

Form 接口(报告 275–283 行)则抽出了"容器如何登记/更新控件"的最小契约:addControl / addFormGroup / getControl / getFormGroup / removeControl / removeFormGroup / updateModel

模板驱动指令(FormsModule 提供)

  • NgForm:selector form:not([ngNoForm]):not([formGroup]):not([formArray]), ng-form, [ngForm]——即任意未禁用表单行为的原生 <form> 都会被接管;输入 ngFormOptions{ updateOn?: FormHooks }),输出 ngSubmit
  • NgModel:selector [ngModel]:not([formControlName]):not([formControl]),输入 namengModel(别名 model)、ngModelOptions{ name?, standalone?, updateOn? })、disabled,输出 ngModelChangeupdate 已弃用);
  • NgModelGroup:selector [ngModelGroup]
  • NgSelectOption:selector option,支持 valuengValue

从 selector 可以读出两条硬性约束:其一,[ngModel][formControl]/[formControlName] 在 selector 层面互斥,报告同时保留了 ReactiveFormsModule.withConfig 中的 warnOnNgModelWithFormControl: 'never' | 'once' | 'always' 配置项用于在运行时兜底警告混用;其二,ngNoForm / ngNoCva 属性提供了对原生 <form> 与内置值访问器的逃生舱。

ControlValueAccessor 体系与注入令牌

报告定义的 ControlValueAccessor 接口是连接控件模型与 DOM 元素的核心契约(实现位于 packages/forms/src/directives/control_value_accessor.ts):

export interface ControlValueAccessor {
  writeValue(obj: any): void;
  registerOnChange(fn: any): void;
  registerOnTouched(fn: any): void;
  setDisabledState?(isDisabled: boolean): void;
}

内置值访问器(BuiltInControlValueAccessor 子类)按 selector 精确匹配不同元素:

值访问器 selector(报告 ɵdir 核心)
DefaultValueAccessor input:not([type=checkbox])textarea(均排除 [ngNoCva]
CheckboxControlValueAccessor input[type=checkbox]
RadioControlValueAccessor input[type=radio],配合 RadioControlRegistry 管理同组单选
SelectControlValueAccessor select:not([multiple]),支持 compareWith
SelectMultipleControlValueAccessor select[multiple]
NumberValueAccessor input[type=number](写回 number | null
RangeValueAccessor input[type=range]

所有内置 selector 都带有 :not([ngNoCva]) 守卫,且同时匹配三种表单指令属性,保证在模板驱动、响应式及独立 ngModel 场景下都能正确接入。

相关注入令牌(报告 671–677 行):

export const NG_VALIDATORS: InjectionToken<readonly (Function | Validator)[]>;
export const NG_ASYNC_VALIDATORS: InjectionToken<readonly (Function | Validator)[]>;
export const NG_VALUE_ACCESSOR: InjectionToken<readonly ControlValueAccessor[]>;
export const COMPOSITION_BUFFER_MODE: InjectionToken<boolean>;
  • NG_VALIDATORS / NG_ASYNC_VALIDATORS:多令牌收集同作用域内的验证器,供 NgControl 在创建控件时装配;
  • NG_VALUE_ACCESSOR:多令牌提供值访问器,NgControl 依此选择(自定义控件可覆盖默认 DOM 绑定);
  • COMPOSITION_BUFFER_MODE:控制 IME 组合输入(如中文输入法)期间是否缓冲变更,DefaultValueAccessor 构造器中的 _compositionMode: boolean 即消费该令牌。

NgControl 是全部控件指令的公共父类,报告暴露了它的扩展点:customControlBindings(支持 value/disabled/touched/dirty/valid/invalid/pending/required/errors 的自定义绑定)、valueAccessor、抽象方法 viewToModelUpdate 等;NgControlStatus / NgControlStatusGroup 则分别针对 [formControlName]/[ngModel]/[formControl] 与分组 selector,把状态类自动绑定到元素上,免去手写 [ngClass]

事件系统与模块配置

报告定义了一套统一的表单事件层次,全部继承自抽象基类 ControlEvent<T>abstract readonly source: AbstractControl<unknown>):

export class ValueChangeEvent<T> extends ControlEvent<T> {
  constructor(value: T, source: AbstractControl);
  readonly value: T;
}
export class StatusChangeEvent extends ControlEvent {
  constructor(status: FormControlStatus, source: AbstractControl);
  readonly status: FormControlStatus;
}
export class TouchedChangeEvent extends ControlEvent {
  constructor(touched: boolean, source: AbstractControl);
  readonly touched: boolean;
}
export class PristineChangeEvent extends ControlEvent {
  constructor(pristine: boolean, source: AbstractControl);
  readonly pristine: boolean;
}
export class FormResetEvent extends ControlEvent { constructor(source: AbstractControl); }
export class FormSubmittedEvent extends ControlEvent { constructor(source: AbstractControl); }

这些事件对象(而非裸值)通过 AbstractControl.events: Observable<ControlEvent<TValue>> 通道分发,订阅方可以按事件类型区分"值变化"、"状态变化"、"touched/pristine 变化"、"重置"与"提交",并始终能拿到 source 控件引用。

两个 NgModule 的配置面:

export class FormsModule {
  static withConfig(opts: { callSetDisabledState?: SetDisabledStateOption }): ModuleWithProviders<FormsModule>;
}
export class ReactiveFormsModule {
  static withConfig(opts: {
    warnOnNgModelWithFormControl?: 'never' | 'once' | 'always';
    callSetDisabledState?: SetDisabledStateOption;
  }): ModuleWithProviders<ReactiveFormsModule>;
}
export type SetDisabledStateOption = 'whenDisabledForLegacyCode' | 'always';

callSetDisabledState: 'always' 要求所有自定义 ControlValueAccessor 必须实现 setDisabledState,从而获得更严格的禁用状态管理;warnOnNgModelWithFormControl 对应前文 selector 无法覆盖的运行时混用场景。报告还保留了四个类型守卫 isFormControl / isFormGroup / isFormArray / isFormRecord,便于在 any 化的控件集合(如遍历 controls)上做运行时判别,以及 VERSIONVersion 类型)用于版本查询。

如何阅读这份 golden:实用技巧

  1. // @public 分层为准:报告中每个成员前的 // @public / // @public (undocumented) 标记是 API 文档化的真实层级;static ɵdirstatic ɵfacstatic ɵprovɵFormControlCtor 等带 ɵ 前缀的成员是 Angular 编译产物(指令声明、工厂、注入声明)的序列化形式,属于"公共但内部"的实现面,业务代码不应依赖;
  2. 与源码对照阅读:模型层对应 packages/forms/src/model/ 下的 abstract_model.tsform_control.tsform_group.tsform_array.ts;指令层对应 packages/forms/src/directives/,其中 ng_model.tsng_form.tsdefault_value_accessor.ts 与报告中的 NgModelNgFormDefaultValueAccessor 一一对应;验证器对应 packages/forms/src/validators.ts
  3. 验证快照一致性:改动 packages/forms 公共 API 后,本地运行 pnpm public-api:check 查看差异,确认符合预期后运行 pnpm public-api:update 重新生成 golden(流程见 goldens/README.mdgoldens/public-api/manage.js);
  4. 注意 API 面的边界:本文件只覆盖 @angular/forms 主入口;同目录还有 errors.api.md 守护错误模块,而信号表单(form() / schema() / [formField],见 packages/forms/PACKAGE.md 的三种构建方式)位于 packages/forms/signals 子入口,拥有独立的 golden 文件,不在这份报告中出现。

小结

goldens/public-api/forms/index.api.md 以 API Extractor 快照的形式,固化了 @angular/forms 的完整公共契约:模型层以 AbstractControl 的"值 / 状态 / 事件"三支柱为核心,向下派生 FormControlFormGroupFormArrayFormRecordFormBuilder 家族提供类型化、非空化、未类型化三档构造体验;验证 API 提供函数式与指令式双通道;指令体系通过互斥的 selector 设计划清模板驱动与响应式两套用法;ControlValueAccessorNG_VALUE_ACCESSOR/NG_VALIDATORS 令牌则是自定义控件与验证器的扩展锚点。理解这份报告,就掌握了在 Angular 中构建、校验、扩展表单时全部可用的公共接口边界。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391