2016-06-22 17:56:10 -04:00
|
|
|
export declare abstract class AbstractControl {
|
2020-07-01 21:16:49 -04:00
|
|
|
get asyncValidator(): AsyncValidatorFn | null;
|
|
|
|
set asyncValidator(asyncValidatorFn: AsyncValidatorFn | null);
|
2019-11-09 13:36:22 -05:00
|
|
|
get dirty(): boolean;
|
|
|
|
get disabled(): boolean;
|
|
|
|
get enabled(): boolean;
|
2017-02-23 12:53:29 -05:00
|
|
|
readonly errors: ValidationErrors | null;
|
2019-11-09 13:36:22 -05:00
|
|
|
get invalid(): boolean;
|
2019-09-13 11:17:18 -04:00
|
|
|
get parent(): FormGroup | FormArray | null;
|
2019-11-09 13:36:22 -05:00
|
|
|
get pending(): boolean;
|
2017-02-07 22:27:01 -05:00
|
|
|
readonly pristine: boolean;
|
2019-11-09 13:36:22 -05:00
|
|
|
get root(): AbstractControl;
|
2017-02-07 22:27:01 -05:00
|
|
|
readonly status: string;
|
|
|
|
readonly statusChanges: Observable<any>;
|
|
|
|
readonly touched: boolean;
|
2019-11-09 13:36:22 -05:00
|
|
|
get untouched(): boolean;
|
|
|
|
get updateOn(): FormHooks;
|
|
|
|
get valid(): boolean;
|
2020-07-01 21:16:49 -04:00
|
|
|
get validator(): ValidatorFn | null;
|
|
|
|
set validator(validatorFn: ValidatorFn | null);
|
2017-02-07 22:27:01 -05:00
|
|
|
readonly value: any;
|
|
|
|
readonly valueChanges: Observable<any>;
|
2020-07-01 21:16:49 -04:00
|
|
|
constructor(validators: ValidatorFn | ValidatorFn[] | null, asyncValidators: AsyncValidatorFn | AsyncValidatorFn[] | null);
|
2016-06-22 17:56:10 -04:00
|
|
|
clearAsyncValidators(): void;
|
|
|
|
clearValidators(): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
disable(opts?: {
|
2016-08-24 19:58:43 -04:00
|
|
|
onlySelf?: boolean;
|
|
|
|
emitEvent?: boolean;
|
|
|
|
}): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
enable(opts?: {
|
2016-08-24 19:58:43 -04:00
|
|
|
onlySelf?: boolean;
|
|
|
|
emitEvent?: boolean;
|
|
|
|
}): void;
|
2017-04-17 14:13:30 -04:00
|
|
|
get(path: Array<string | number> | string): AbstractControl | null;
|
2018-12-21 19:39:37 -05:00
|
|
|
getError(errorCode: string, path?: Array<string | number> | string): any;
|
|
|
|
hasError(errorCode: string, path?: Array<string | number> | string): boolean;
|
2018-10-29 04:36:17 -04:00
|
|
|
markAllAsTouched(): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
markAsDirty(opts?: {
|
2016-06-22 17:56:10 -04:00
|
|
|
onlySelf?: boolean;
|
|
|
|
}): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
markAsPending(opts?: {
|
2016-06-22 17:56:10 -04:00
|
|
|
onlySelf?: boolean;
|
2017-11-06 03:59:09 -05:00
|
|
|
emitEvent?: boolean;
|
2016-06-22 17:56:10 -04:00
|
|
|
}): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
markAsPristine(opts?: {
|
2016-07-12 18:02:25 -04:00
|
|
|
onlySelf?: boolean;
|
|
|
|
}): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
markAsTouched(opts?: {
|
2016-07-01 18:36:04 -04:00
|
|
|
onlySelf?: boolean;
|
|
|
|
}): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
markAsUntouched(opts?: {
|
2016-07-12 18:02:25 -04:00
|
|
|
onlySelf?: boolean;
|
|
|
|
}): void;
|
2016-08-05 16:35:17 -04:00
|
|
|
abstract patchValue(value: any, options?: Object): void;
|
2016-07-12 18:02:25 -04:00
|
|
|
abstract reset(value?: any, options?: Object): void;
|
2017-11-10 03:09:22 -05:00
|
|
|
setAsyncValidators(newValidator: AsyncValidatorFn | AsyncValidatorFn[] | null): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
setErrors(errors: ValidationErrors | null, opts?: {
|
2016-06-22 17:56:10 -04:00
|
|
|
emitEvent?: boolean;
|
|
|
|
}): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
setParent(parent: FormGroup | FormArray): void;
|
2017-04-17 14:13:30 -04:00
|
|
|
setValidators(newValidator: ValidatorFn | ValidatorFn[] | null): void;
|
2016-08-05 16:35:17 -04:00
|
|
|
abstract setValue(value: any, options?: Object): void;
|
2017-06-12 13:59:29 -04:00
|
|
|
updateValueAndValidity(opts?: {
|
2016-06-23 21:19:32 -04:00
|
|
|
onlySelf?: boolean;
|
|
|
|
emitEvent?: boolean;
|
|
|
|
}): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare abstract class AbstractControlDirective {
|
2019-11-09 13:36:22 -05:00
|
|
|
abstract get control(): AbstractControl | null;
|
|
|
|
get dirty(): boolean | null;
|
|
|
|
get disabled(): boolean | null;
|
|
|
|
get enabled(): boolean | null;
|
|
|
|
get errors(): ValidationErrors | null;
|
|
|
|
get invalid(): boolean | null;
|
|
|
|
get path(): string[] | null;
|
|
|
|
get pending(): boolean | null;
|
|
|
|
get pristine(): boolean | null;
|
|
|
|
get status(): string | null;
|
|
|
|
get statusChanges(): Observable<any> | null;
|
|
|
|
get touched(): boolean | null;
|
|
|
|
get untouched(): boolean | null;
|
|
|
|
get valid(): boolean | null;
|
|
|
|
get value(): any;
|
|
|
|
get valueChanges(): Observable<any> | null;
|
2018-12-21 19:39:37 -05:00
|
|
|
getError(errorCode: string, path?: Array<string | number> | string): any;
|
|
|
|
hasError(errorCode: string, path?: Array<string | number> | string): boolean;
|
2016-07-12 18:02:25 -04:00
|
|
|
reset(value?: any): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare interface AbstractControlOptions {
|
2018-01-31 22:25:14 -05:00
|
|
|
asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null;
|
|
|
|
updateOn?: 'change' | 'blur' | 'submit';
|
|
|
|
validators?: ValidatorFn | ValidatorFn[] | null;
|
|
|
|
}
|
|
|
|
|
2016-07-07 23:14:42 -04:00
|
|
|
export declare class AbstractFormGroupDirective extends ControlContainer implements OnInit, OnDestroy {
|
2019-11-09 13:36:22 -05:00
|
|
|
get asyncValidator(): AsyncValidatorFn | null;
|
|
|
|
get control(): FormGroup;
|
|
|
|
get formDirective(): Form | null;
|
|
|
|
get path(): string[];
|
|
|
|
get validator(): ValidatorFn | null;
|
2016-07-07 23:14:42 -04:00
|
|
|
ngOnDestroy(): void;
|
|
|
|
ngOnInit(): void;
|
|
|
|
}
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare interface AsyncValidator extends Validator {
|
2018-09-20 10:18:14 -04:00
|
|
|
validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
|
2017-02-20 19:26:51 -05:00
|
|
|
}
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare interface AsyncValidatorFn {
|
2018-09-20 10:18:14 -04:00
|
|
|
(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
|
2016-06-24 21:24:11 -04:00
|
|
|
}
|
|
|
|
|
2016-06-22 17:56:10 -04:00
|
|
|
export declare class CheckboxControlValueAccessor implements ControlValueAccessor {
|
|
|
|
onChange: (_: any) => void;
|
|
|
|
onTouched: () => void;
|
2017-06-20 05:35:16 -04:00
|
|
|
constructor(_renderer: Renderer2, _elementRef: ElementRef);
|
2016-06-22 17:56:10 -04:00
|
|
|
registerOnChange(fn: (_: any) => {}): void;
|
|
|
|
registerOnTouched(fn: () => {}): void;
|
2016-08-24 19:58:43 -04:00
|
|
|
setDisabledState(isDisabled: boolean): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
writeValue(value: any): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2016-12-10 05:44:04 -05:00
|
|
|
export declare class CheckboxRequiredValidator extends RequiredValidator {
|
2018-09-20 10:18:14 -04:00
|
|
|
validate(control: AbstractControl): ValidationErrors | null;
|
2016-12-10 05:44:04 -05:00
|
|
|
}
|
|
|
|
|
fix(forms): make composition event buffering configurable (#15256)
This commit fixes a regression where `ngModel` no longer syncs
letter by letter on Android devices, and instead syncs at the
end of every word. This broke when we introduced buffering of
IME events so IMEs like Pinyin keyboards or Katakana keyboards
wouldn't display composition strings. Unfortunately, iOS devices
and Android devices have opposite event behavior. Whereas iOS
devices fire composition events for IME keyboards only, Android
fires composition events for Latin-language keyboards. For
this reason, languages like English don't work as expected on
Android if we always buffer. So to support both platforms,
composition string buffering will only be turned on by default
for non-Android devices.
However, we have also added a `COMPOSITION_BUFFER_MODE` token
to make this configurable by the application. In some cases, apps
might might still want to receive intermediate values. For example,
some inputs begin searching based on Latin letters before a
character selection is made.
As a provider, this is fairly flexible. If you want to turn
composition buffering off, simply provide the token at the top
level:
```ts
providers: [
{provide: COMPOSITION_BUFFER_MODE, useValue: false}
]
```
Or, if you want to change the mode based on locale or platform,
you can use a factory:
```ts
import {shouldUseBuffering} from 'my/lib';
....
providers: [
{provide: COMPOSITION_BUFFER_MODE, useFactory: shouldUseBuffering}
]
```
Closes #15079.
PR Close #15256
2017-03-20 20:38:33 -04:00
|
|
|
export declare const COMPOSITION_BUFFER_MODE: InjectionToken<boolean>;
|
|
|
|
|
2017-04-17 14:13:30 -04:00
|
|
|
export declare abstract class ControlContainer extends AbstractControlDirective {
|
2019-11-09 13:36:22 -05:00
|
|
|
get formDirective(): Form | null;
|
2019-09-10 16:39:47 -04:00
|
|
|
name: string | number | null;
|
2019-11-09 13:36:22 -05:00
|
|
|
get path(): string[] | null;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare interface ControlValueAccessor {
|
2016-06-22 17:56:10 -04:00
|
|
|
registerOnChange(fn: any): void;
|
|
|
|
registerOnTouched(fn: any): void;
|
2016-08-24 19:58:43 -04:00
|
|
|
setDisabledState?(isDisabled: boolean): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
writeValue(obj: any): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class DefaultValueAccessor implements ControlValueAccessor {
|
|
|
|
onChange: (_: any) => void;
|
|
|
|
onTouched: () => void;
|
2017-06-20 05:35:16 -04:00
|
|
|
constructor(_renderer: Renderer2, _elementRef: ElementRef, _compositionMode: boolean);
|
2016-06-22 17:56:10 -04:00
|
|
|
registerOnChange(fn: (_: any) => void): void;
|
|
|
|
registerOnTouched(fn: () => void): void;
|
2016-08-24 19:58:43 -04:00
|
|
|
setDisabledState(isDisabled: boolean): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
writeValue(value: any): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2016-12-29 12:07:02 -05:00
|
|
|
export declare class EmailValidator implements Validator {
|
2019-11-09 13:36:22 -05:00
|
|
|
set email(value: boolean | string);
|
2016-12-29 12:07:02 -05:00
|
|
|
registerOnValidatorChange(fn: () => void): void;
|
2018-09-20 10:18:14 -04:00
|
|
|
validate(control: AbstractControl): ValidationErrors | null;
|
2016-12-29 12:07:02 -05:00
|
|
|
}
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare interface Form {
|
2016-06-22 17:56:10 -04:00
|
|
|
addControl(dir: NgControl): void;
|
|
|
|
addFormGroup(dir: AbstractFormGroupDirective): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
getControl(dir: NgControl): FormControl;
|
2016-06-22 17:56:10 -04:00
|
|
|
getFormGroup(dir: AbstractFormGroupDirective): FormGroup;
|
2016-06-23 21:19:32 -04:00
|
|
|
removeControl(dir: NgControl): void;
|
|
|
|
removeFormGroup(dir: AbstractFormGroupDirective): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
updateModel(dir: NgControl, value: any): void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export declare class FormArray extends AbstractControl {
|
|
|
|
controls: AbstractControl[];
|
2019-11-09 13:36:22 -05:00
|
|
|
get length(): number;
|
2017-07-25 18:01:04 -04:00
|
|
|
constructor(controls: AbstractControl[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
|
2016-06-22 17:56:10 -04:00
|
|
|
at(index: number): AbstractControl;
|
2019-02-21 23:47:07 -05:00
|
|
|
clear(): void;
|
2016-08-24 19:58:43 -04:00
|
|
|
getRawValue(): any[];
|
2016-06-22 17:56:10 -04:00
|
|
|
insert(index: number, control: AbstractControl): void;
|
2017-04-27 16:39:21 -04:00
|
|
|
patchValue(value: any[], options?: {
|
2016-08-05 16:35:17 -04:00
|
|
|
onlySelf?: boolean;
|
2016-10-19 12:54:54 -04:00
|
|
|
emitEvent?: boolean;
|
2016-08-05 16:35:17 -04:00
|
|
|
}): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
push(control: AbstractControl): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
removeAt(index: number): void;
|
2017-04-27 16:39:21 -04:00
|
|
|
reset(value?: any, options?: {
|
2016-07-12 18:02:25 -04:00
|
|
|
onlySelf?: boolean;
|
2016-10-19 12:54:54 -04:00
|
|
|
emitEvent?: boolean;
|
2016-07-12 18:02:25 -04:00
|
|
|
}): void;
|
2016-09-02 18:57:35 -04:00
|
|
|
setControl(index: number, control: AbstractControl): void;
|
2017-04-27 16:39:21 -04:00
|
|
|
setValue(value: any[], options?: {
|
2016-07-08 16:04:25 -04:00
|
|
|
onlySelf?: boolean;
|
2016-10-19 12:54:54 -04:00
|
|
|
emitEvent?: boolean;
|
2016-07-08 16:04:25 -04:00
|
|
|
}): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2016-06-25 16:27:29 -04:00
|
|
|
export declare class FormArrayName extends ControlContainer implements OnInit, OnDestroy {
|
2019-11-09 13:36:22 -05:00
|
|
|
get asyncValidator(): AsyncValidatorFn | null;
|
|
|
|
get control(): FormArray;
|
|
|
|
get formDirective(): FormGroupDirective | null;
|
2019-09-10 16:39:47 -04:00
|
|
|
name: string | number | null;
|
2019-11-09 13:36:22 -05:00
|
|
|
get path(): string[];
|
|
|
|
get validator(): ValidatorFn | null;
|
2020-09-22 21:00:37 -04:00
|
|
|
constructor(parent: ControlContainer, validators: (Validator | ValidatorFn)[], asyncValidators: (AsyncValidator | AsyncValidatorFn)[]);
|
2016-06-25 16:27:29 -04:00
|
|
|
ngOnDestroy(): void;
|
|
|
|
ngOnInit(): void;
|
|
|
|
}
|
|
|
|
|
2016-06-22 17:56:10 -04:00
|
|
|
export declare class FormBuilder {
|
2018-06-20 13:21:46 -04:00
|
|
|
array(controlsConfig: any[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): FormArray;
|
|
|
|
control(formState: any, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): FormControl;
|
2016-06-22 17:56:10 -04:00
|
|
|
group(controlsConfig: {
|
|
|
|
[key: string]: any;
|
2018-11-07 14:38:07 -05:00
|
|
|
}, options?: AbstractControlOptions | {
|
2016-06-22 17:56:10 -04:00
|
|
|
[key: string]: any;
|
2017-04-17 14:13:30 -04:00
|
|
|
} | null): FormGroup;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class FormControl extends AbstractControl {
|
2017-07-25 18:01:04 -04:00
|
|
|
constructor(formState?: any, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
|
2016-08-05 16:35:17 -04:00
|
|
|
patchValue(value: any, options?: {
|
|
|
|
onlySelf?: boolean;
|
|
|
|
emitEvent?: boolean;
|
|
|
|
emitModelToViewChange?: boolean;
|
|
|
|
emitViewToModelChange?: boolean;
|
|
|
|
}): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
registerOnChange(fn: Function): void;
|
2016-08-24 19:58:43 -04:00
|
|
|
registerOnDisabledChange(fn: (isDisabled: boolean) => void): void;
|
2017-04-27 16:39:21 -04:00
|
|
|
reset(formState?: any, options?: {
|
2016-07-12 18:02:25 -04:00
|
|
|
onlySelf?: boolean;
|
2016-10-19 12:54:54 -04:00
|
|
|
emitEvent?: boolean;
|
2016-07-12 18:02:25 -04:00
|
|
|
}): void;
|
2017-04-27 16:39:21 -04:00
|
|
|
setValue(value: any, options?: {
|
2016-08-05 16:35:17 -04:00
|
|
|
onlySelf?: boolean;
|
|
|
|
emitEvent?: boolean;
|
|
|
|
emitModelToViewChange?: boolean;
|
|
|
|
emitViewToModelChange?: boolean;
|
|
|
|
}): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class FormControlDirective extends NgControl implements OnChanges {
|
2019-11-09 13:36:22 -05:00
|
|
|
get asyncValidator(): AsyncValidatorFn | null;
|
|
|
|
get control(): FormControl;
|
2016-06-22 17:56:10 -04:00
|
|
|
form: FormControl;
|
2019-11-09 13:36:22 -05:00
|
|
|
set isDisabled(isDisabled: boolean);
|
refactor(forms): deprecate ngModel usage on same field as formControl (#22633)
Support for using the `ngModel` input property and `ngModelChange`
event with reactive form directives has been deprecated in
Angular v6 and will be removed in Angular v7.
Now deprecated:
```html
<input [formControl]="control" [(ngModel)]="value">
```
```ts
this.value = 'some value';
```
This has been deprecated for a few reasons. First, developers have
found this pattern confusing. It seems like the actual `ngModel`
directive is being used, but in fact it's an input/output property
named `ngModel` on the reactive form directive that simply approximates
(some of) its behavior. Specifically, it allows getting/setting the
value and intercepting value events. However, some of `ngModel`'s other
features - like delaying updates with`ngModelOptions` or exporting the
directive - simply don't work, which has understandably caused some
confusion.
In addition, this pattern mixes template-driven and reactive forms
strategies, which we generally don't recommend because it doesn't take
advantage of the full benefits of either strategy. Setting the value in
the template violates the template-agnostic principles behind reactive
forms, whereas adding a FormControl/FormGroup layer in the class removes
the convenience of defining forms in the template.
To update your code before v7, you'll want to decide whether to stick
with reactive form directives (and get/set values using reactive forms
patterns) or switch over to template-driven directives.
After (choice 1 - use reactive forms):
```html
<input [formControl]="control">
```
```ts
this.control.setValue('some value');
```
After (choice 2 - use template-driven forms):
```html
<input [(ngModel)]="value">
```
```ts
this.value = 'some value';
```
You can also choose to silence this warning by providing a config for
`ReactiveFormsModule` at import time:
```ts
imports: [
ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
]
```
Alternatively, you can choose to surface a separate warning for each
instance of this pattern with a config value of `"always"`. This may
help to track down where in the code the pattern is being used as the
code is being updated.
Note: `warnOnNgModelWithFormControl` is set up as deprecated so that it
can be removed in v7 when it is no longer needed. This will not display
properly in API docs yet because dgeni doesn't yet support deprecating
properties in object literals, but we have an open issue to resolve the
discrepancy here: https://github.com/angular/angular/issues/22640.
PR Close #22633
2018-03-07 12:46:10 -05:00
|
|
|
/** @deprecated */ model: any;
|
2019-11-09 13:36:22 -05:00
|
|
|
get path(): string[];
|
2019-07-17 20:49:16 -04:00
|
|
|
/** @deprecated */ update: EventEmitter<any>;
|
2019-11-09 13:36:22 -05:00
|
|
|
get validator(): ValidatorFn | null;
|
2016-06-23 21:19:32 -04:00
|
|
|
viewModel: any;
|
2020-09-22 21:00:37 -04:00
|
|
|
constructor(validators: (Validator | ValidatorFn)[], asyncValidators: (AsyncValidator | AsyncValidatorFn)[], valueAccessors: ControlValueAccessor[], _ngModelWarningConfig: string | null);
|
2016-06-22 17:56:10 -04:00
|
|
|
ngOnChanges(changes: SimpleChanges): void;
|
|
|
|
viewToModelUpdate(newValue: any): void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export declare class FormControlName extends NgControl implements OnChanges, OnDestroy {
|
2019-11-09 13:36:22 -05:00
|
|
|
get asyncValidator(): AsyncValidatorFn;
|
2017-02-07 22:27:01 -05:00
|
|
|
readonly control: FormControl;
|
2019-11-09 13:36:22 -05:00
|
|
|
get formDirective(): any;
|
|
|
|
set isDisabled(isDisabled: boolean);
|
refactor(forms): deprecate ngModel usage on same field as formControl (#22633)
Support for using the `ngModel` input property and `ngModelChange`
event with reactive form directives has been deprecated in
Angular v6 and will be removed in Angular v7.
Now deprecated:
```html
<input [formControl]="control" [(ngModel)]="value">
```
```ts
this.value = 'some value';
```
This has been deprecated for a few reasons. First, developers have
found this pattern confusing. It seems like the actual `ngModel`
directive is being used, but in fact it's an input/output property
named `ngModel` on the reactive form directive that simply approximates
(some of) its behavior. Specifically, it allows getting/setting the
value and intercepting value events. However, some of `ngModel`'s other
features - like delaying updates with`ngModelOptions` or exporting the
directive - simply don't work, which has understandably caused some
confusion.
In addition, this pattern mixes template-driven and reactive forms
strategies, which we generally don't recommend because it doesn't take
advantage of the full benefits of either strategy. Setting the value in
the template violates the template-agnostic principles behind reactive
forms, whereas adding a FormControl/FormGroup layer in the class removes
the convenience of defining forms in the template.
To update your code before v7, you'll want to decide whether to stick
with reactive form directives (and get/set values using reactive forms
patterns) or switch over to template-driven directives.
After (choice 1 - use reactive forms):
```html
<input [formControl]="control">
```
```ts
this.control.setValue('some value');
```
After (choice 2 - use template-driven forms):
```html
<input [(ngModel)]="value">
```
```ts
this.value = 'some value';
```
You can also choose to silence this warning by providing a config for
`ReactiveFormsModule` at import time:
```ts
imports: [
ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
]
```
Alternatively, you can choose to surface a separate warning for each
instance of this pattern with a config value of `"always"`. This may
help to track down where in the code the pattern is being used as the
code is being updated.
Note: `warnOnNgModelWithFormControl` is set up as deprecated so that it
can be removed in v7 when it is no longer needed. This will not display
properly in API docs yet because dgeni doesn't yet support deprecating
properties in object literals, but we have an open issue to resolve the
discrepancy here: https://github.com/angular/angular/issues/22640.
PR Close #22633
2018-03-07 12:46:10 -05:00
|
|
|
/** @deprecated */ model: any;
|
2019-05-22 04:22:13 -04:00
|
|
|
name: string | number | null;
|
2019-11-09 13:36:22 -05:00
|
|
|
get path(): string[];
|
2019-07-17 20:49:16 -04:00
|
|
|
/** @deprecated */ update: EventEmitter<any>;
|
2019-11-09 13:36:22 -05:00
|
|
|
get validator(): ValidatorFn | null;
|
2020-09-22 21:00:37 -04:00
|
|
|
constructor(parent: ControlContainer, validators: (Validator | ValidatorFn)[], asyncValidators: (AsyncValidator | AsyncValidatorFn)[], valueAccessors: ControlValueAccessor[], _ngModelWarningConfig: string | null);
|
2016-06-22 17:56:10 -04:00
|
|
|
ngOnChanges(changes: SimpleChanges): void;
|
|
|
|
ngOnDestroy(): void;
|
|
|
|
viewToModelUpdate(newValue: any): void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export declare class FormGroup extends AbstractControl {
|
|
|
|
controls: {
|
|
|
|
[key: string]: AbstractControl;
|
|
|
|
};
|
|
|
|
constructor(controls: {
|
|
|
|
[key: string]: AbstractControl;
|
2017-07-25 18:01:04 -04:00
|
|
|
}, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
|
2016-06-22 17:56:10 -04:00
|
|
|
addControl(name: string, control: AbstractControl): void;
|
|
|
|
contains(controlName: string): boolean;
|
2016-11-08 18:44:36 -05:00
|
|
|
getRawValue(): any;
|
2016-08-05 16:35:17 -04:00
|
|
|
patchValue(value: {
|
|
|
|
[key: string]: any;
|
2017-04-27 16:39:21 -04:00
|
|
|
}, options?: {
|
2016-08-05 16:35:17 -04:00
|
|
|
onlySelf?: boolean;
|
2016-10-19 12:54:54 -04:00
|
|
|
emitEvent?: boolean;
|
2016-08-05 16:35:17 -04:00
|
|
|
}): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
registerControl(name: string, control: AbstractControl): AbstractControl;
|
|
|
|
removeControl(name: string): void;
|
2017-04-27 16:39:21 -04:00
|
|
|
reset(value?: any, options?: {
|
2016-07-12 18:02:25 -04:00
|
|
|
onlySelf?: boolean;
|
2016-10-19 12:54:54 -04:00
|
|
|
emitEvent?: boolean;
|
2016-07-12 18:02:25 -04:00
|
|
|
}): void;
|
2016-09-02 18:57:35 -04:00
|
|
|
setControl(name: string, control: AbstractControl): void;
|
2016-08-05 16:35:17 -04:00
|
|
|
setValue(value: {
|
2016-07-08 16:04:25 -04:00
|
|
|
[key: string]: any;
|
2017-04-27 16:39:21 -04:00
|
|
|
}, options?: {
|
2016-07-08 16:04:25 -04:00
|
|
|
onlySelf?: boolean;
|
2016-10-19 12:54:54 -04:00
|
|
|
emitEvent?: boolean;
|
2016-07-08 16:04:25 -04:00
|
|
|
}): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class FormGroupDirective extends ControlContainer implements Form, OnChanges {
|
2019-11-09 13:36:22 -05:00
|
|
|
get control(): FormGroup;
|
2016-09-02 18:57:35 -04:00
|
|
|
directives: FormControlName[];
|
2016-06-22 17:56:10 -04:00
|
|
|
form: FormGroup;
|
2019-11-09 13:36:22 -05:00
|
|
|
get formDirective(): Form;
|
2019-07-17 20:49:16 -04:00
|
|
|
ngSubmit: EventEmitter<any>;
|
2019-11-09 13:36:22 -05:00
|
|
|
get path(): string[];
|
2017-02-07 22:27:01 -05:00
|
|
|
readonly submitted: boolean;
|
2020-09-22 21:00:37 -04:00
|
|
|
constructor(_validators: (Validator | ValidatorFn)[], _asyncValidators: (AsyncValidator | AsyncValidatorFn)[]);
|
2016-09-02 18:57:35 -04:00
|
|
|
addControl(dir: FormControlName): FormControl;
|
2016-06-25 16:27:29 -04:00
|
|
|
addFormArray(dir: FormArrayName): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
addFormGroup(dir: FormGroupName): void;
|
2016-09-02 18:57:35 -04:00
|
|
|
getControl(dir: FormControlName): FormControl;
|
2016-06-25 16:27:29 -04:00
|
|
|
getFormArray(dir: FormArrayName): FormArray;
|
2016-06-23 21:19:32 -04:00
|
|
|
getFormGroup(dir: FormGroupName): FormGroup;
|
|
|
|
ngOnChanges(changes: SimpleChanges): void;
|
2016-07-12 18:02:25 -04:00
|
|
|
onReset(): void;
|
2016-10-11 18:49:36 -04:00
|
|
|
onSubmit($event: Event): boolean;
|
2016-09-02 18:57:35 -04:00
|
|
|
removeControl(dir: FormControlName): void;
|
2016-06-25 16:27:29 -04:00
|
|
|
removeFormArray(dir: FormArrayName): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
removeFormGroup(dir: FormGroupName): void;
|
2016-08-12 02:27:33 -04:00
|
|
|
resetForm(value?: any): void;
|
2016-09-02 18:57:35 -04:00
|
|
|
updateModel(dir: FormControlName, value: any): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class FormGroupName extends AbstractFormGroupDirective implements OnInit, OnDestroy {
|
2019-09-10 16:39:47 -04:00
|
|
|
name: string | number | null;
|
2020-09-22 21:00:37 -04:00
|
|
|
constructor(parent: ControlContainer, validators: (Validator | ValidatorFn)[], asyncValidators: (AsyncValidator | AsyncValidatorFn)[]);
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
feat(forms): add modules for forms and deprecatedForms (#9859)
Closes #9732
BREAKING CHANGE:
We have removed the deprecated form directives from the built-in platform directive list, so apps are not required to package forms with their app. This also makes forms friendly to offline compilation.
Instead, we have exposed three modules:
OLD API:
- `DeprecatedFormsModule`
NEW API:
- `FormsModule`
- `ReactiveFormsModule`
If you provide one of these modules, the default forms directives and providers from that module will be available to you app-wide. Note: You can provide both the `FormsModule` and the `ReactiveFormsModule` together if you like, but they are fully-functional separately.
**Before:**
```ts
import {disableDeprecatedForms, provideForms} from @angular/forms;
bootstrap(App, [
disableDeprecatedForms(),
provideForms()
]);
```
**After:**
```ts
import {DeprecatedFormsModule} from @angular/common;
bootstrap(App, {modules: [DeprecatedFormsModule] });
```
-OR-
```ts
import {FormsModule} from @angular/forms;
bootstrap(App, {modules: [FormsModule] });
```
-OR-
```ts
import {ReactiveFormsModule} from @angular/forms;
bootstrap(App, {modules: [ReactiveFormsModule] });
```
You can also choose not to provide any forms module and run your app without forms.
Or you can choose not to provide any forms module *and* provide form directives at will. This will allow you to use the deprecatedForms API for some components and not others.
```
import {FORM_DIRECTIVES, FORM_PROVIDERS} from @angular/forms;
@Component({
selector: some-comp,
directives: [FORM_DIRECTIVES],
providers: [FORM_PROVIDERS]
})
class SomeComp
```
2016-07-07 14:32:51 -04:00
|
|
|
export declare class FormsModule {
|
|
|
|
}
|
|
|
|
|
2016-08-06 02:53:41 -04:00
|
|
|
export declare class MaxLengthValidator implements Validator, OnChanges {
|
2019-08-08 13:19:41 -04:00
|
|
|
maxlength: string | number;
|
2016-08-06 02:53:41 -04:00
|
|
|
ngOnChanges(changes: SimpleChanges): void;
|
2016-09-09 17:09:11 -04:00
|
|
|
registerOnValidatorChange(fn: () => void): void;
|
2018-09-20 10:18:14 -04:00
|
|
|
validate(control: AbstractControl): ValidationErrors | null;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2016-08-06 02:53:41 -04:00
|
|
|
export declare class MinLengthValidator implements Validator, OnChanges {
|
2019-08-08 13:19:41 -04:00
|
|
|
minlength: string | number;
|
2016-08-06 02:53:41 -04:00
|
|
|
ngOnChanges(changes: SimpleChanges): void;
|
2016-09-09 17:09:11 -04:00
|
|
|
registerOnValidatorChange(fn: () => void): void;
|
2018-09-20 10:18:14 -04:00
|
|
|
validate(control: AbstractControl): ValidationErrors | null;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2017-01-03 19:54:46 -05:00
|
|
|
export declare const NG_ASYNC_VALIDATORS: InjectionToken<(Function | Validator)[]>;
|
2016-06-22 17:56:10 -04:00
|
|
|
|
2017-01-03 19:54:46 -05:00
|
|
|
export declare const NG_VALIDATORS: InjectionToken<(Function | Validator)[]>;
|
2016-06-22 17:56:10 -04:00
|
|
|
|
2020-05-08 03:06:35 -04:00
|
|
|
export declare const NG_VALUE_ACCESSOR: InjectionToken<readonly ControlValueAccessor[]>;
|
2016-06-22 17:56:10 -04:00
|
|
|
|
|
|
|
export declare abstract class NgControl extends AbstractControlDirective {
|
2019-11-09 13:36:22 -05:00
|
|
|
get asyncValidator(): AsyncValidatorFn | null;
|
2019-05-22 04:22:13 -04:00
|
|
|
name: string | number | null;
|
2019-11-09 13:36:22 -05:00
|
|
|
get validator(): ValidatorFn | null;
|
2017-04-17 14:13:30 -04:00
|
|
|
valueAccessor: ControlValueAccessor | null;
|
2016-06-22 17:56:10 -04:00
|
|
|
abstract viewToModelUpdate(newValue: any): void;
|
|
|
|
}
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare class NgControlStatus extends ɵangular_packages_forms_forms_g {
|
2016-06-23 21:19:32 -04:00
|
|
|
constructor(cd: NgControl);
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare class NgControlStatusGroup extends ɵangular_packages_forms_forms_g {
|
2016-08-11 12:01:09 -04:00
|
|
|
constructor(cd: ControlContainer);
|
|
|
|
}
|
|
|
|
|
2017-08-08 17:37:29 -04:00
|
|
|
export declare class NgForm extends ControlContainer implements Form, AfterViewInit {
|
2019-11-09 13:36:22 -05:00
|
|
|
get control(): FormGroup;
|
|
|
|
get controls(): {
|
2016-06-22 17:56:10 -04:00
|
|
|
[key: string]: AbstractControl;
|
|
|
|
};
|
2016-06-23 21:19:32 -04:00
|
|
|
form: FormGroup;
|
2019-11-09 13:36:22 -05:00
|
|
|
get formDirective(): Form;
|
2019-07-17 20:49:16 -04:00
|
|
|
ngSubmit: EventEmitter<any>;
|
2017-08-08 17:37:29 -04:00
|
|
|
options: {
|
|
|
|
updateOn?: FormHooks;
|
|
|
|
};
|
2019-11-09 13:36:22 -05:00
|
|
|
get path(): string[];
|
2017-02-07 22:27:01 -05:00
|
|
|
readonly submitted: boolean;
|
2020-09-22 21:00:37 -04:00
|
|
|
constructor(validators: (Validator | ValidatorFn)[], asyncValidators: (AsyncValidator | AsyncValidatorFn)[]);
|
2016-06-22 17:56:10 -04:00
|
|
|
addControl(dir: NgModel): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
addFormGroup(dir: NgModelGroup): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
getControl(dir: NgModel): FormControl;
|
2016-06-23 21:19:32 -04:00
|
|
|
getFormGroup(dir: NgModelGroup): FormGroup;
|
2017-08-08 17:37:29 -04:00
|
|
|
ngAfterViewInit(): void;
|
2016-07-12 18:02:25 -04:00
|
|
|
onReset(): void;
|
2016-10-11 18:49:36 -04:00
|
|
|
onSubmit($event: Event): boolean;
|
2016-06-22 17:56:10 -04:00
|
|
|
removeControl(dir: NgModel): void;
|
|
|
|
removeFormGroup(dir: NgModelGroup): void;
|
2016-08-12 02:27:33 -04:00
|
|
|
resetForm(value?: any): void;
|
2016-08-05 16:35:17 -04:00
|
|
|
setValue(value: {
|
2016-07-08 16:04:25 -04:00
|
|
|
[key: string]: any;
|
|
|
|
}): void;
|
2016-08-05 16:35:17 -04:00
|
|
|
updateModel(dir: NgControl, value: any): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class NgModel extends NgControl implements OnChanges, OnDestroy {
|
2019-11-09 13:36:22 -05:00
|
|
|
get asyncValidator(): AsyncValidatorFn | null;
|
2017-02-07 22:27:01 -05:00
|
|
|
readonly control: FormControl;
|
2019-11-09 13:36:22 -05:00
|
|
|
get formDirective(): any;
|
2016-08-25 17:56:31 -04:00
|
|
|
isDisabled: boolean;
|
2016-06-22 17:56:10 -04:00
|
|
|
model: any;
|
|
|
|
name: string;
|
|
|
|
options: {
|
|
|
|
name?: string;
|
|
|
|
standalone?: boolean;
|
2017-08-08 00:11:46 -04:00
|
|
|
updateOn?: FormHooks;
|
2016-06-22 17:56:10 -04:00
|
|
|
};
|
2019-11-09 13:36:22 -05:00
|
|
|
get path(): string[];
|
2019-07-17 20:49:16 -04:00
|
|
|
update: EventEmitter<any>;
|
2019-11-09 13:36:22 -05:00
|
|
|
get validator(): ValidatorFn | null;
|
2016-06-23 21:19:32 -04:00
|
|
|
viewModel: any;
|
2020-09-22 21:00:37 -04:00
|
|
|
constructor(parent: ControlContainer, validators: (Validator | ValidatorFn)[], asyncValidators: (AsyncValidator | AsyncValidatorFn)[], valueAccessors: ControlValueAccessor[]);
|
2016-06-22 17:56:10 -04:00
|
|
|
ngOnChanges(changes: SimpleChanges): void;
|
|
|
|
ngOnDestroy(): void;
|
|
|
|
viewToModelUpdate(newValue: any): void;
|
2019-12-19 17:34:36 -05:00
|
|
|
static ngAcceptInputType_isDisabled: boolean | string;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class NgModelGroup extends AbstractFormGroupDirective implements OnInit, OnDestroy {
|
|
|
|
name: string;
|
2020-09-22 21:00:37 -04:00
|
|
|
constructor(parent: ControlContainer, validators: (Validator | ValidatorFn)[], asyncValidators: (AsyncValidator | AsyncValidatorFn)[]);
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class NgSelectOption implements OnDestroy {
|
|
|
|
id: string;
|
2019-11-09 13:36:22 -05:00
|
|
|
set ngValue(value: any);
|
|
|
|
set value(value: any);
|
2017-06-20 05:35:16 -04:00
|
|
|
constructor(_element: ElementRef, _renderer: Renderer2, _select: SelectControlValueAccessor);
|
2016-06-22 17:56:10 -04:00
|
|
|
ngOnDestroy(): void;
|
|
|
|
}
|
|
|
|
|
2018-12-13 14:11:15 -05:00
|
|
|
export declare class NumberValueAccessor implements ControlValueAccessor {
|
|
|
|
onChange: (_: any) => void;
|
|
|
|
onTouched: () => void;
|
|
|
|
constructor(_renderer: Renderer2, _elementRef: ElementRef);
|
|
|
|
registerOnChange(fn: (_: number | null) => void): void;
|
|
|
|
registerOnTouched(fn: () => void): void;
|
|
|
|
setDisabledState(isDisabled: boolean): void;
|
|
|
|
writeValue(value: number): void;
|
|
|
|
}
|
|
|
|
|
2016-08-06 02:53:41 -04:00
|
|
|
export declare class PatternValidator implements Validator, OnChanges {
|
2017-02-23 12:53:29 -05:00
|
|
|
pattern: string | RegExp;
|
2016-08-06 02:53:41 -04:00
|
|
|
ngOnChanges(changes: SimpleChanges): void;
|
2016-09-09 17:09:11 -04:00
|
|
|
registerOnValidatorChange(fn: () => void): void;
|
2018-09-20 10:18:14 -04:00
|
|
|
validate(control: AbstractControl): ValidationErrors | null;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2016-09-19 13:41:20 -04:00
|
|
|
export declare class RadioControlValueAccessor implements ControlValueAccessor, OnDestroy, OnInit {
|
|
|
|
formControlName: string;
|
|
|
|
name: string;
|
|
|
|
onChange: () => void;
|
|
|
|
onTouched: () => void;
|
|
|
|
value: any;
|
2020-02-26 12:09:35 -05:00
|
|
|
constructor(_renderer: Renderer2, _elementRef: ElementRef, _registry: ɵangular_packages_forms_forms_n, _injector: Injector);
|
2016-09-19 13:41:20 -04:00
|
|
|
fireUncheck(value: any): void;
|
|
|
|
ngOnDestroy(): void;
|
|
|
|
ngOnInit(): void;
|
|
|
|
registerOnChange(fn: (_: any) => {}): void;
|
|
|
|
registerOnTouched(fn: () => {}): void;
|
|
|
|
setDisabledState(isDisabled: boolean): void;
|
|
|
|
writeValue(value: any): void;
|
|
|
|
}
|
|
|
|
|
2018-12-13 14:11:15 -05:00
|
|
|
export declare class RangeValueAccessor implements ControlValueAccessor {
|
|
|
|
onChange: (_: any) => void;
|
|
|
|
onTouched: () => void;
|
|
|
|
constructor(_renderer: Renderer2, _elementRef: ElementRef);
|
|
|
|
registerOnChange(fn: (_: number | null) => void): void;
|
|
|
|
registerOnTouched(fn: () => void): void;
|
|
|
|
setDisabledState(isDisabled: boolean): void;
|
|
|
|
writeValue(value: any): void;
|
|
|
|
}
|
|
|
|
|
feat(forms): add modules for forms and deprecatedForms (#9859)
Closes #9732
BREAKING CHANGE:
We have removed the deprecated form directives from the built-in platform directive list, so apps are not required to package forms with their app. This also makes forms friendly to offline compilation.
Instead, we have exposed three modules:
OLD API:
- `DeprecatedFormsModule`
NEW API:
- `FormsModule`
- `ReactiveFormsModule`
If you provide one of these modules, the default forms directives and providers from that module will be available to you app-wide. Note: You can provide both the `FormsModule` and the `ReactiveFormsModule` together if you like, but they are fully-functional separately.
**Before:**
```ts
import {disableDeprecatedForms, provideForms} from @angular/forms;
bootstrap(App, [
disableDeprecatedForms(),
provideForms()
]);
```
**After:**
```ts
import {DeprecatedFormsModule} from @angular/common;
bootstrap(App, {modules: [DeprecatedFormsModule] });
```
-OR-
```ts
import {FormsModule} from @angular/forms;
bootstrap(App, {modules: [FormsModule] });
```
-OR-
```ts
import {ReactiveFormsModule} from @angular/forms;
bootstrap(App, {modules: [ReactiveFormsModule] });
```
You can also choose not to provide any forms module and run your app without forms.
Or you can choose not to provide any forms module *and* provide form directives at will. This will allow you to use the deprecatedForms API for some components and not others.
```
import {FORM_DIRECTIVES, FORM_PROVIDERS} from @angular/forms;
@Component({
selector: some-comp,
directives: [FORM_DIRECTIVES],
providers: [FORM_PROVIDERS]
})
class SomeComp
```
2016-07-07 14:32:51 -04:00
|
|
|
export declare class ReactiveFormsModule {
|
refactor(forms): deprecate ngModel usage on same field as formControl (#22633)
Support for using the `ngModel` input property and `ngModelChange`
event with reactive form directives has been deprecated in
Angular v6 and will be removed in Angular v7.
Now deprecated:
```html
<input [formControl]="control" [(ngModel)]="value">
```
```ts
this.value = 'some value';
```
This has been deprecated for a few reasons. First, developers have
found this pattern confusing. It seems like the actual `ngModel`
directive is being used, but in fact it's an input/output property
named `ngModel` on the reactive form directive that simply approximates
(some of) its behavior. Specifically, it allows getting/setting the
value and intercepting value events. However, some of `ngModel`'s other
features - like delaying updates with`ngModelOptions` or exporting the
directive - simply don't work, which has understandably caused some
confusion.
In addition, this pattern mixes template-driven and reactive forms
strategies, which we generally don't recommend because it doesn't take
advantage of the full benefits of either strategy. Setting the value in
the template violates the template-agnostic principles behind reactive
forms, whereas adding a FormControl/FormGroup layer in the class removes
the convenience of defining forms in the template.
To update your code before v7, you'll want to decide whether to stick
with reactive form directives (and get/set values using reactive forms
patterns) or switch over to template-driven directives.
After (choice 1 - use reactive forms):
```html
<input [formControl]="control">
```
```ts
this.control.setValue('some value');
```
After (choice 2 - use template-driven forms):
```html
<input [(ngModel)]="value">
```
```ts
this.value = 'some value';
```
You can also choose to silence this warning by providing a config for
`ReactiveFormsModule` at import time:
```ts
imports: [
ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
]
```
Alternatively, you can choose to surface a separate warning for each
instance of this pattern with a config value of `"always"`. This may
help to track down where in the code the pattern is being used as the
code is being updated.
Note: `warnOnNgModelWithFormControl` is set up as deprecated so that it
can be removed in v7 when it is no longer needed. This will not display
properly in API docs yet because dgeni doesn't yet support deprecating
properties in object literals, but we have an open issue to resolve the
discrepancy here: https://github.com/angular/angular/issues/22640.
PR Close #22633
2018-03-07 12:46:10 -05:00
|
|
|
static withConfig(opts: { warnOnNgModelWithFormControl: 'never' | 'once' | 'always';
|
2018-07-09 14:36:30 -04:00
|
|
|
}): ModuleWithProviders<ReactiveFormsModule>;
|
feat(forms): add modules for forms and deprecatedForms (#9859)
Closes #9732
BREAKING CHANGE:
We have removed the deprecated form directives from the built-in platform directive list, so apps are not required to package forms with their app. This also makes forms friendly to offline compilation.
Instead, we have exposed three modules:
OLD API:
- `DeprecatedFormsModule`
NEW API:
- `FormsModule`
- `ReactiveFormsModule`
If you provide one of these modules, the default forms directives and providers from that module will be available to you app-wide. Note: You can provide both the `FormsModule` and the `ReactiveFormsModule` together if you like, but they are fully-functional separately.
**Before:**
```ts
import {disableDeprecatedForms, provideForms} from @angular/forms;
bootstrap(App, [
disableDeprecatedForms(),
provideForms()
]);
```
**After:**
```ts
import {DeprecatedFormsModule} from @angular/common;
bootstrap(App, {modules: [DeprecatedFormsModule] });
```
-OR-
```ts
import {FormsModule} from @angular/forms;
bootstrap(App, {modules: [FormsModule] });
```
-OR-
```ts
import {ReactiveFormsModule} from @angular/forms;
bootstrap(App, {modules: [ReactiveFormsModule] });
```
You can also choose not to provide any forms module and run your app without forms.
Or you can choose not to provide any forms module *and* provide form directives at will. This will allow you to use the deprecatedForms API for some components and not others.
```
import {FORM_DIRECTIVES, FORM_PROVIDERS} from @angular/forms;
@Component({
selector: some-comp,
directives: [FORM_DIRECTIVES],
providers: [FORM_PROVIDERS]
})
class SomeComp
```
2016-07-07 14:32:51 -04:00
|
|
|
}
|
2016-06-22 17:56:10 -04:00
|
|
|
|
2016-08-06 02:53:41 -04:00
|
|
|
export declare class RequiredValidator implements Validator {
|
2019-11-09 13:36:22 -05:00
|
|
|
get required(): boolean | string;
|
|
|
|
set required(value: boolean | string);
|
2016-09-09 17:09:11 -04:00
|
|
|
registerOnValidatorChange(fn: () => void): void;
|
2018-09-20 10:18:14 -04:00
|
|
|
validate(control: AbstractControl): ValidationErrors | null;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export declare class SelectControlValueAccessor implements ControlValueAccessor {
|
2019-11-09 13:36:22 -05:00
|
|
|
set compareWith(fn: (o1: any, o2: any) => boolean);
|
2016-06-22 17:56:10 -04:00
|
|
|
onChange: (_: any) => void;
|
|
|
|
onTouched: () => void;
|
2016-06-23 21:19:32 -04:00
|
|
|
value: any;
|
2017-06-20 05:35:16 -04:00
|
|
|
constructor(_renderer: Renderer2, _elementRef: ElementRef);
|
2016-06-22 17:56:10 -04:00
|
|
|
registerOnChange(fn: (value: any) => any): void;
|
|
|
|
registerOnTouched(fn: () => any): void;
|
2016-08-24 19:58:43 -04:00
|
|
|
setDisabledState(isDisabled: boolean): void;
|
2016-06-23 21:19:32 -04:00
|
|
|
writeValue(value: any): void;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2016-06-30 21:04:00 -04:00
|
|
|
export declare class SelectMultipleControlValueAccessor implements ControlValueAccessor {
|
2019-11-09 13:36:22 -05:00
|
|
|
set compareWith(fn: (o1: any, o2: any) => boolean);
|
2016-06-30 21:04:00 -04:00
|
|
|
onChange: (_: any) => void;
|
|
|
|
onTouched: () => void;
|
|
|
|
value: any;
|
2017-06-20 05:35:16 -04:00
|
|
|
constructor(_renderer: Renderer2, _elementRef: ElementRef);
|
2016-06-30 21:04:00 -04:00
|
|
|
registerOnChange(fn: (value: any) => any): void;
|
|
|
|
registerOnTouched(fn: () => any): void;
|
2016-08-24 19:58:43 -04:00
|
|
|
setDisabledState(isDisabled: boolean): void;
|
2016-06-30 21:04:00 -04:00
|
|
|
writeValue(value: any): void;
|
|
|
|
}
|
|
|
|
|
2017-02-23 12:53:29 -05:00
|
|
|
export declare type ValidationErrors = {
|
|
|
|
[key: string]: any;
|
|
|
|
};
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare interface Validator {
|
2016-09-09 17:09:11 -04:00
|
|
|
registerOnValidatorChange?(fn: () => void): void;
|
2018-09-20 10:18:14 -04:00
|
|
|
validate(control: AbstractControl): ValidationErrors | null;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
|
|
|
|
2020-02-26 12:09:35 -05:00
|
|
|
export declare interface ValidatorFn {
|
2018-09-20 10:18:14 -04:00
|
|
|
(control: AbstractControl): ValidationErrors | null;
|
2016-06-24 21:24:11 -04:00
|
|
|
}
|
|
|
|
|
2016-06-22 17:56:10 -04:00
|
|
|
export declare class Validators {
|
2017-04-28 12:48:15 -04:00
|
|
|
static compose(validators: null): null;
|
2020-01-24 13:55:39 -05:00
|
|
|
static compose(validators: (ValidatorFn | null | undefined)[]): ValidatorFn | null;
|
2017-04-17 14:13:30 -04:00
|
|
|
static composeAsync(validators: (AsyncValidatorFn | null)[]): AsyncValidatorFn | null;
|
2017-02-23 12:53:29 -05:00
|
|
|
static email(control: AbstractControl): ValidationErrors | null;
|
2017-04-06 11:41:10 -04:00
|
|
|
static max(max: number): ValidatorFn;
|
2016-06-23 21:19:32 -04:00
|
|
|
static maxLength(maxLength: number): ValidatorFn;
|
2017-04-06 11:41:10 -04:00
|
|
|
static min(min: number): ValidatorFn;
|
2016-06-23 21:19:32 -04:00
|
|
|
static minLength(minLength: number): ValidatorFn;
|
2018-09-20 10:18:14 -04:00
|
|
|
static nullValidator(control: AbstractControl): ValidationErrors | null;
|
2016-10-19 12:37:54 -04:00
|
|
|
static pattern(pattern: string | RegExp): ValidatorFn;
|
2017-02-23 12:53:29 -05:00
|
|
|
static required(control: AbstractControl): ValidationErrors | null;
|
|
|
|
static requiredTrue(control: AbstractControl): ValidationErrors | null;
|
2016-06-22 17:56:10 -04:00
|
|
|
}
|
2016-11-30 16:52:08 -05:00
|
|
|
|
|
|
|
export declare const VERSION: Version;
|