feat(forms): add updateOn and ngFormOptions to NgForm

This commit introduces a new Input property called
`ngFormOptions` to the `NgForm` directive. You can use it
to set default `updateOn` values for all the form's child
controls. This default will be used unless the child has
already explicitly set its own `updateOn` value in
`ngModelOptions`.

Potential values: `change` | `blur` | `submit`

```html
<form [ngFormOptions]="{updateOn: blur}">
  <input name="one" ngModel>  <!-- will update on blur-->
</form>
```

For more context, see [#18577](https://github.com/angular/angular/pull/18577).
This commit is contained in:
Kara Erickson
2017-08-08 14:37:29 -07:00
committed by Hans
parent 43226cb93d
commit 0d45828460
3 changed files with 156 additions and 8 deletions

View File

@ -6,9 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Directive, EventEmitter, Inject, Optional, Self, forwardRef} from '@angular/core';
import {AfterViewInit, Directive, EventEmitter, Inject, Input, Optional, Self, forwardRef} from '@angular/core';
import {AbstractControl, FormControl, FormGroup} from '../model';
import {AbstractControl, FormControl, FormGroup, FormHooks} from '../model';
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
import {ControlContainer} from './control_container';
@ -63,13 +63,30 @@ const resolvedPromise = Promise.resolve(null);
outputs: ['ngSubmit'],
exportAs: 'ngForm'
})
export class NgForm extends ControlContainer implements Form {
export class NgForm extends ControlContainer implements Form,
AfterViewInit {
private _submitted: boolean = false;
private _directives: NgModel[] = [];
form: FormGroup;
ngSubmit = new EventEmitter();
/**
* Options for the `NgForm` instance. Accepts the following properties:
*
* **updateOn**: Serves as the default `updateOn` value for all child `NgModels` below it
* (unless a child has explicitly set its own value for this in `ngModelOptions`).
* Potential values: `'change'` | `'blur'` | `'submit'`
*
* ```html
* <form [ngFormOptions]="{updateOn: 'blur'}">
* <input name="one" ngModel> <!-- this ngModel will update on blur -->
* </form>
* ```
*
*/
@Input('ngFormOptions') options: {updateOn?: FormHooks};
constructor(
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
@ -78,6 +95,8 @@ export class NgForm extends ControlContainer implements Form {
new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators));
}
ngAfterViewInit() { this._setUpdateStrategy(); }
get submitted(): boolean { return this._submitted; }
get formDirective(): Form { return this; }
@ -154,6 +173,12 @@ export class NgForm extends ControlContainer implements Form {
this._submitted = false;
}
private _setUpdateStrategy() {
if (this.options && this.options.updateOn != null) {
this.form._updateOn = this.options.updateOn;
}
}
/** @internal */
_findContainer(path: string[]): FormGroup {
path.pop();