docs(forms): update form apis based on review feedback (#25724)

PR Close #25724
This commit is contained in:
Brandon Roberts 2018-09-17 14:36:00 -05:00 committed by Kara Erickson
parent 07c10e2844
commit a9a81f91cf
7 changed files with 75 additions and 104 deletions

View File

@ -14,7 +14,7 @@ import {ValidationErrors} from './validators';
* @description * @description
* Base class for control directives. * Base class for control directives.
* *
* This class is only used internally in the `FormsModule`. * This class is only used internally in the `ReactiveFormsModule` and the `FormsModule`.
* *
*/ */
export abstract class AbstractControlDirective { export abstract class AbstractControlDirective {
@ -28,114 +28,94 @@ export abstract class AbstractControlDirective {
/** /**
* @description * @description
* The value of the control. * Reports the value of the control if it is present, otherwise null.
*
* @returns The value of the control if it is present, otherwise null.
*/ */
get value(): any { return this.control ? this.control.value : null; } get value(): any { return this.control ? this.control.value : null; }
/** /**
* @description * @description
* Reports that the control is valid, meaning that no errors exist in the input value. * Reports whether the control is valid. A control is considered valid if no
* * validation errors exist with the current value.
* @returns The control's valid state if the control is present, otherwise null. * If the control is not present, null is returned.
*/ */
get valid(): boolean|null { return this.control ? this.control.valid : null; } get valid(): boolean|null { return this.control ? this.control.valid : null; }
/** /**
* @description * @description
* Reports that the control is invalid, meaning that an error exists in the input value. * Reports whether the control is invalid, meaning that an error exists in the input value.
* * If the control is not present, null is returned.
* @returns The control's invalid state if the control is present, otherwise null.
*/ */
get invalid(): boolean|null { return this.control ? this.control.invalid : null; } get invalid(): boolean|null { return this.control ? this.control.invalid : null; }
/** /**
* @description * @description
* Reports that a control is pending, meaning that that async validation is occurring and * Reports whether a control is pending, meaning that that async validation is occurring and
* errors are not yet available for the input value. * errors are not yet available for the input value. If the control is not present, null is
* * returned.
* @returns The control's pending state if the control is present, otherwise null.
*/ */
get pending(): boolean|null { return this.control ? this.control.pending : null; } get pending(): boolean|null { return this.control ? this.control.pending : null; }
/** /**
* @description * @description
* Reports that the control is disabled, meaning that the control is exempt from ancestor * Reports whether the control is disabled, meaning that the control is disabled
* calculations of validity or value. * in the UI and is exempt from validation checks and excluded from aggregate
* * values of ancestor controls. If the control is not present, null is returned.
* @returns The control's disabled state if the control is present, otherwise null.
*/ */
get disabled(): boolean|null { return this.control ? this.control.disabled : null; } get disabled(): boolean|null { return this.control ? this.control.disabled : null; }
/** /**
* @description * @description
* Reports that the control is enabled, meaning that the control is included in ancestor * Reports whether the control is enabled, meaning that the control is included in ancestor
* calculations of validity or value. * calculations of validity or value. If the control is not present, null is returned.
*
* @returns The control's enabled state if the control is present, otherwise null.
*/ */
get enabled(): boolean|null { return this.control ? this.control.enabled : null; } get enabled(): boolean|null { return this.control ? this.control.enabled : null; }
/** /**
* @description * @description
* Reports the FormControl validation errors. * Reports the control's validation errors. If the control is not present, null is returned.
*
* @returns The control's validation errors if the control is present, otherwise null.
*/ */
get errors(): ValidationErrors|null { return this.control ? this.control.errors : null; } get errors(): ValidationErrors|null { return this.control ? this.control.errors : null; }
/** /**
* @description * @description
* Reports that the control is pristine, meaning that the control the user has not yet changed * Reports whether the control is pristine, meaning that the user has not yet changed
* the value in the UI. * the value in the UI. If the control is not present, null is returned.
*
* @returns The control's pristine state if the control is present, otherwise null.
*/ */
get pristine(): boolean|null { return this.control ? this.control.pristine : null; } get pristine(): boolean|null { return this.control ? this.control.pristine : null; }
/** /**
* @description * @description
* Reports that the control is dirty, meaning that the control the user has changed * Reports whether the control is dirty, meaning that the user has changed
* the value in the UI. * the value in the UI. If the control is not present, null is returned.
*
* @returns The control's dirty state if the control is present, otherwise null.
*/ */
get dirty(): boolean|null { return this.control ? this.control.dirty : null; } get dirty(): boolean|null { return this.control ? this.control.dirty : null; }
/** /**
* @description * @description
* Reports that the control is touched, meaning that the the user has triggered * Reports whether the control is touched, meaning that the user has triggered
* a `blur` event on it. * a `blur` event on it. If the control is not present, null is returned.
*
* @returns The control's touched state if the control is present, otherwise null.
*/ */
get touched(): boolean|null { return this.control ? this.control.touched : null; } get touched(): boolean|null { return this.control ? this.control.touched : null; }
/** /**
* @description * @description
* Reports that a FormControl is touched, meaning that the the user has triggered * Reports the validation status of the control. Possible values include:
* a `blur` event on it. * 'VALID', 'INVALID', 'DISABLED', and 'PENDING'.
* * If the control is not present, null is returned.
* @returns The control's touched state if the control is present, otherwise null.
*/ */
get status(): string|null { return this.control ? this.control.status : null; } get status(): string|null { return this.control ? this.control.status : null; }
/** /**
* @description * @description
* Reports that a FormControl is untouched, meaning that the the user has not yet triggered * Reports whether the control is untouched, meaning that the user has not yet triggered
* a `blur` event on it. * a `blur` event on it. If the control is not present, null is returned.
*
* @returns The control's untouched state if the control is present, otherwise null.
*/ */
get untouched(): boolean|null { return this.control ? this.control.untouched : null; } get untouched(): boolean|null { return this.control ? this.control.untouched : null; }
/** /**
* @description * @description
* Reports the observable of status changes for the control. * Returns a multicasting observable that emits a validation status whenever it is
* * calculated for the control. If the control is not present, null is returned.
* @returns An observable that emits every time the validation status of the control
* is re-calculated if the control is present, otherwise null.
*/ */
get statusChanges(): Observable<any>|null { get statusChanges(): Observable<any>|null {
return this.control ? this.control.statusChanges : null; return this.control ? this.control.statusChanges : null;
@ -143,10 +123,9 @@ export abstract class AbstractControlDirective {
/** /**
* @description * @description
* Reports the observable of value changes for the control. * Returns a multicasting observable of value changes for the control that emits every time the
* * value of the control changes in the UI or programmatically.
* @returns An observable that emits every time the value of the control * If the control is not present, null is returned.
* changes in the UI or programmatically if the control is present, otherwise null.
*/ */
get valueChanges(): Observable<any>|null { get valueChanges(): Observable<any>|null {
return this.control ? this.control.valueChanges : null; return this.control ? this.control.valueChanges : null;
@ -154,16 +133,14 @@ export abstract class AbstractControlDirective {
/** /**
* @description * @description
* Reports an array that represents the path from the top-level form to this control. * Returns an array that represents the path from the top-level form to this control.
* Each index is the string name of the control on that level. * Each index is the string name of the control on that level.
*
*/ */
get path(): string[]|null { return null; } get path(): string[]|null { return null; }
/** /**
* @description * @description
* Resets the control with the provided value if the control is present * Resets the control with the provided value if the control is present.
*
*/ */
reset(value: any = undefined): void { reset(value: any = undefined): void {
if (this.control) this.control.reset(value); if (this.control) this.control.reset(value);
@ -173,8 +150,7 @@ export abstract class AbstractControlDirective {
* @description * @description
* Reports whether the control with the given path has the error specified. * Reports whether the control with the given path has the error specified.
* If no path is given, it checks for the error on the present control. * If no path is given, it checks for the error on the present control.
* * If the control is not present, false is returned.
* @returns True if the control is present and has the error specified, otherwise false
*/ */
hasError(errorCode: string, path?: string[]): boolean { hasError(errorCode: string, path?: string[]): boolean {
return this.control ? this.control.hasError(errorCode, path) : false; return this.control ? this.control.hasError(errorCode, path) : false;
@ -182,10 +158,8 @@ export abstract class AbstractControlDirective {
/** /**
* @description * @description
* Reports error data for the control with the given path. Otherwise * Reports error data for the control with the given path.
* returns null or undefined. * If the control is not present, null is returned.
*
* @returns The control's error if the control is present, otherwise null
*/ */
getError(errorCode: string, path?: string[]): any { getError(errorCode: string, path?: string[]): any {
return this.control ? this.control.getError(errorCode, path) : null; return this.control ? this.control.getError(errorCode, path) : null;

View File

@ -52,7 +52,7 @@ export class AbstractFormGroupDirective extends ControlContainer implements OnIn
/** /**
* @description * @description
* The callback method triggered on the instance after the inputs are set. * An internal callback method triggered on the instance after the inputs are set.
* Registers the group with its parent group. * Registers the group with its parent group.
*/ */
ngOnInit(): void { ngOnInit(): void {
@ -62,7 +62,7 @@ export class AbstractFormGroupDirective extends ControlContainer implements OnIn
/** /**
* @description * @description
* The callback method trigger before the instance is destroyed. * An internal callback method triggered before the instance is destroyed.
* Removes the group from its parent group. * Removes the group from its parent group.
*/ */
ngOnDestroy(): void { ngOnDestroy(): void {
@ -73,33 +73,31 @@ export class AbstractFormGroupDirective extends ControlContainer implements OnIn
/** /**
* @description * @description
* Reports the `FormGroup` bound to this directive from its parent * The `FormGroup` bound to this directive.
*/ */
get control(): FormGroup { return this.formDirective !.getFormGroup(this); } get control(): FormGroup { return this.formDirective !.getFormGroup(this); }
/** /**
* @description * @description
* Reports the path to this group * The path to this group from the top-level directive.
*/ */
get path(): string[] { return controlPath(this.name, this._parent); } get path(): string[] { return controlPath(this.name, this._parent); }
/** /**
* @description * @description
* Reports the parent form for this group * The top-level directive for this group if present, otherwise null.
*
* @returns The parent form if present, otherwise null.
*/ */
get formDirective(): Form|null { return this._parent ? this._parent.formDirective : null; } get formDirective(): Form|null { return this._parent ? this._parent.formDirective : null; }
/** /**
* @description * @description
* Reports the synchronous validators registered with this group * The synchronous validators registered with this group.
*/ */
get validator(): ValidatorFn|null { return composeValidators(this._validators); } get validator(): ValidatorFn|null { return composeValidators(this._validators); }
/** /**
* @description * @description
* Reports the async validators registered with this group * The async validators registered with this group.
*/ */
get asyncValidator(): AsyncValidatorFn|null { get asyncValidator(): AsyncValidatorFn|null {
return composeAsyncValidators(this._asyncValidators); return composeAsyncValidators(this._asyncValidators);

View File

@ -25,13 +25,13 @@ export abstract class ControlContainer extends AbstractControlDirective {
/** /**
* @description * @description
* Reports the parent form for the control * The top-level form directive for the control.
*/ */
get formDirective(): Form|null { return null; } get formDirective(): Form|null { return null; }
/** /**
* @description * @description
* Reports the path to this group * The path to this group.
*/ */
get path(): string[]|null { return null; } get path(): string[]|null { return null; }
} }

View File

@ -55,7 +55,7 @@ export interface ControlValueAccessor {
* *
* The following example stores the provided function as an internal method. * The following example stores the provided function as an internal method.
* *
* ```typescript * ```ts
* registerOnChange(fn: (_: any) => void): void { * registerOnChange(fn: (_: any) => void): void {
* this._onChange = fn; * this._onChange = fn;
* } * }
@ -64,7 +64,7 @@ export interface ControlValueAccessor {
* When the value changes in the UI, call the registered * When the value changes in the UI, call the registered
* function to allow the forms API to update itself: * function to allow the forms API to update itself:
* *
* ```typescript * ```ts
* host: { * host: {
* (change): '_onChange($event.target.value)' * (change): '_onChange($event.target.value)'
* } * }
@ -76,10 +76,8 @@ export interface ControlValueAccessor {
/** /**
* @description * @description
* Registers a callback function that is called when the control receives a blur event. * Registers a callback function is called by the forms API on initialization
* * to update the form model on blur.
* This is called by the forms API on initialization so it can update the form model
* on blur.
* *
* When implementing `registerOnTouched` in your own value accessor, save the given * When implementing `registerOnTouched` in your own value accessor, save the given
* function so your class calls it when the control should be considered * function so your class calls it when the control should be considered
@ -87,7 +85,7 @@ export interface ControlValueAccessor {
* *
* ### Store the callback function * ### Store the callback function
* *
* The folliwing example stores the provided function as an internal method. * The following example stores the provided function as an internal method.
* *
* ```ts * ```ts
* registerOnTouched(fn: any): void { * registerOnTouched(fn: any): void {
@ -95,7 +93,7 @@ export interface ControlValueAccessor {
* } * }
* ``` * ```
* *
* On blur (or equivalent), your class calls the registered function to allow * On blur (or equivalent), your class should call the registered function to allow
* the forms API to update itself: * the forms API to update itself:
* *
* ```ts * ```ts
@ -110,8 +108,8 @@ export interface ControlValueAccessor {
/** /**
* @description * @description
* Registers a callback function that is called when the control status is disabled or * Function that is called by the forms API when the control status changes to
* re-enabled. Depending on the status, it enables or disables the * or from 'DISABLED'. Depending on the status, it enables or disables the
* appropriate DOM element. * appropriate DOM element.
* *
* The following is an example of writing the disabled property to a native DOM element: * The following is an example of writing the disabled property to a native DOM element:

View File

@ -17,14 +17,14 @@ import {NgControl} from './ng_control';
* @description * @description
* An interface implemented by `FormGroupDirective` and `NgForm` directives. * An interface implemented by `FormGroupDirective` and `NgForm` directives.
* *
* Only used by the `FormsModule`. * Only used by the `ReactiveFormsModule` and `FormsModule`.
*/ */
export interface Form { export interface Form {
/** /**
* @description * @description
* Add a control to this form. * Add a control to this form.
* *
* @param dir The control to add to the form * @param dir The control directive to add to the form.
*/ */
addControl(dir: NgControl): void; addControl(dir: NgControl): void;
@ -32,15 +32,15 @@ export interface Form {
* @description * @description
* Remove a control from this form. * Remove a control from this form.
* *
* @param dir: The control to remove from the form * @param dir: The control directive to remove from the form.
*/ */
removeControl(dir: NgControl): void; removeControl(dir: NgControl): void;
/** /**
* @description * @description
* Reports the `FormControl` associated with the provided `NgControl`. * The control directive from which to get the `FormControl`.
* *
* @param dir: The form control instance * @param dir: The control directive.
*/ */
getControl(dir: NgControl): FormControl; getControl(dir: NgControl): FormControl;
@ -48,7 +48,7 @@ export interface Form {
* @description * @description
* Add a group of controls to this form. * Add a group of controls to this form.
* *
* @param dir: The control group to remove * @param dir: The control group directive to add.
*/ */
addFormGroup(dir: AbstractFormGroupDirective): void; addFormGroup(dir: AbstractFormGroupDirective): void;
@ -56,15 +56,15 @@ export interface Form {
* @description * @description
* Remove a group of controls to this form. * Remove a group of controls to this form.
* *
* @param dir: The control group to remove * @param dir: The control group directive to remove.
*/ */
removeFormGroup(dir: AbstractFormGroupDirective): void; removeFormGroup(dir: AbstractFormGroupDirective): void;
/** /**
* @description * @description
* Reports the form group for the provided control * The `FormGroup` associated with a particular `AbstractFormGroupDirective`.
* *
* @param dir: The form group to query * @param dir: The form group directive from which to get the `FormGroup`.
*/ */
getFormGroup(dir: AbstractFormGroupDirective): FormGroup; getFormGroup(dir: AbstractFormGroupDirective): FormGroup;
@ -72,8 +72,8 @@ export interface Form {
* @description * @description
* Update the model for a particular control with a new value. * Update the model for a particular control with a new value.
* *
* @param dir: The control to update * @param dir: The control directive to update.
* @param value: The new value for the control * @param value: The new value for the control.
*/ */
updateModel(dir: NgControl, value: any): void; updateModel(dir: NgControl, value: any): void;
} }

View File

@ -18,13 +18,14 @@ function unimplemented(): any {
/** /**
* @description * @description
* A base class that all control directives extend. It binds a `FormControl` object to a * A base class that all control `FormControl`-based directives extend. It binds a `FormControl`
* DOM element and is only used internally by Angular forms. * object to a DOM element.
*/ */
export abstract class NgControl extends AbstractControlDirective { export abstract class NgControl extends AbstractControlDirective {
/** /**
* @description * @description
* The parent form for the control * The parent form for the control.
*
* @internal * @internal
*/ */
_parent: ControlContainer|null = null; _parent: ControlContainer|null = null;

View File

@ -36,11 +36,11 @@ export type ValidationErrors = {
* *
* ```typescript * ```typescript
* @Directive({ * @Directive({
* selector: '[custom-validator]', * selector: '[customValidator]',
* providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}] * providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]
* }) * })
* class CustomValidatorDirective implements Validator { * class CustomValidatorDirective implements Validator {
* validate(c: AbstractControl): {[key: string]: any} { * validate(c: AbstractControl): ValidationErrors|null {
* return {'custom': true}; * return {'custom': true};
* } * }
* } * }
@ -49,7 +49,7 @@ export type ValidationErrors = {
export interface Validator { export interface Validator {
/** /**
* @description * @description
* Method that performs synchronous verification against the provided control. * Method that performs synchronous validation against the provided control.
* *
* @param c The control to validate against. * @param c The control to validate against.
* *
@ -82,12 +82,12 @@ export interface Validator {
* import { of as observableOf } from 'rxjs'; * import { of as observableOf } from 'rxjs';
* *
* @Directive({ * @Directive({
* selector: '[custom-async-validator]', * selector: '[customAsyncValidator]',
* providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: CustomAsyncValidatorDirective, multi: * providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: CustomAsyncValidatorDirective, multi:
* true}] * true}]
* }) * })
* class CustomAsyncValidatorDirective implements AsyncValidator { * class CustomAsyncValidatorDirective implements AsyncValidator {
* validate(c: AbstractControl): Observable<{[key: string]: any}> { * validate(c: AbstractControl): Observable<ValidationErrors|null> {
* return observableOf({'custom': true}); * return observableOf({'custom': true});
* } * }
* } * }
@ -98,7 +98,7 @@ export interface Validator {
export interface AsyncValidator extends Validator { export interface AsyncValidator extends Validator {
/** /**
* @description * @description
* Method that performs async verification against the provided control. * Method that performs async validation against the provided control.
* *
* @param c The control to validate against. * @param c The control to validate against.
* *