fix(forms): separate ngModelGroup from formGroupName
This commit is contained in:
parent
bc888bf3a1
commit
5c0cfdee48
|
@ -22,15 +22,16 @@ export {CheckboxControlValueAccessor} from './forms/directives/checkbox_value_ac
|
|||
export {ControlContainer} from './forms/directives/control_container';
|
||||
export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './forms/directives/control_value_accessor';
|
||||
export {DefaultValueAccessor} from './forms/directives/default_value_accessor';
|
||||
export {FormControlName} from './forms/directives/form_control_name';
|
||||
export {Form} from './forms/directives/form_interface';
|
||||
export {NgControl} from './forms/directives/ng_control';
|
||||
export {NgControlGroup} from './forms/directives/ng_control_group';
|
||||
export {NgControlStatus} from './forms/directives/ng_control_status';
|
||||
export {NgForm} from './forms/directives/ng_form';
|
||||
export {NgModel} from './forms/directives/ng_model';
|
||||
export {NgModelGroup} from './forms/directives/ng_model_group';
|
||||
export {FormControlDirective} from './forms/directives/reactive_directives/form_control_directive';
|
||||
export {FormControlName} from './forms/directives/reactive_directives/form_control_name';
|
||||
export {FormGroupDirective} from './forms/directives/reactive_directives/form_group_directive';
|
||||
export {FormGroupName} from './forms/directives/reactive_directives/form_group_name';
|
||||
export {NgSelectOption, SelectControlValueAccessor} from './forms/directives/select_control_value_accessor';
|
||||
export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator, Validator} from './forms/directives/validators';
|
||||
export {FormBuilder} from './forms/form_builder';
|
||||
|
|
|
@ -2,15 +2,16 @@ import {Type} from '@angular/core';
|
|||
|
||||
import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||
import {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||
import {FormControlName} from './directives/form_control_name';
|
||||
import {NgControlGroup} from './directives/ng_control_group';
|
||||
import {NgControlStatus} from './directives/ng_control_status';
|
||||
import {NgForm} from './directives/ng_form';
|
||||
import {NgModel} from './directives/ng_model';
|
||||
import {NgModelGroup} from './directives/ng_model_group';
|
||||
import {NumberValueAccessor} from './directives/number_value_accessor';
|
||||
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||
import {FormControlDirective} from './directives/reactive_directives/form_control_directive';
|
||||
import {FormControlName} from './directives/reactive_directives/form_control_name';
|
||||
import {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
|
||||
import {FormGroupName} from './directives/reactive_directives/form_group_name';
|
||||
import {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
||||
import {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
||||
import {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators';
|
||||
|
@ -18,16 +19,17 @@ import {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValida
|
|||
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||
export {ControlValueAccessor} from './directives/control_value_accessor';
|
||||
export {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||
export {FormControlName} from './directives/form_control_name';
|
||||
export {NgControl} from './directives/ng_control';
|
||||
export {NgControlGroup} from './directives/ng_control_group';
|
||||
export {NgControlStatus} from './directives/ng_control_status';
|
||||
export {NgForm} from './directives/ng_form';
|
||||
export {NgModel} from './directives/ng_model';
|
||||
export {NgModelGroup} from './directives/ng_model_group';
|
||||
export {NumberValueAccessor} from './directives/number_value_accessor';
|
||||
export {RadioButtonState, RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||
export {FormControlDirective} from './directives/reactive_directives/form_control_directive';
|
||||
export {FormControlName} from './directives/reactive_directives/form_control_name';
|
||||
export {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
|
||||
export {FormGroupName} from './directives/reactive_directives/form_group_name';
|
||||
export {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
||||
export {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
||||
export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators';
|
||||
|
@ -52,9 +54,7 @@ export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValida
|
|||
* @experimental
|
||||
*/
|
||||
export const FORM_DIRECTIVES: Type[] = /*@ts2dart_const*/[
|
||||
NgControlGroup,
|
||||
|
||||
NgModel, NgForm,
|
||||
NgModel, NgModelGroup, NgForm,
|
||||
|
||||
NgSelectOption, NgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor,
|
||||
CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor,
|
||||
|
@ -64,4 +64,4 @@ export const FORM_DIRECTIVES: Type[] = /*@ts2dart_const*/[
|
|||
];
|
||||
|
||||
export const REACTIVE_FORM_DIRECTIVES: Type[] =
|
||||
/*@ts2dart_const*/[FormControlDirective, FormGroupDirective, FormControlName];
|
||||
/*@ts2dart_const*/[FormControlDirective, FormGroupDirective, FormControlName, FormGroupName];
|
|
@ -0,0 +1,46 @@
|
|||
import {OnDestroy, OnInit} from '@angular/core';
|
||||
|
||||
import {FormGroup} from '../model';
|
||||
|
||||
import {ControlContainer} from './control_container';
|
||||
import {Form} from './form_interface';
|
||||
import {composeAsyncValidators, composeValidators, controlPath} from './shared';
|
||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||
|
||||
/**
|
||||
This is a base class for code shared between {@link NgModelGroup} and {@link FormGroupName}.
|
||||
*/
|
||||
|
||||
export class AbstractFormGroupDirective extends ControlContainer implements OnInit, OnDestroy {
|
||||
/** @internal */
|
||||
_parent: ControlContainer;
|
||||
|
||||
/** @internal */
|
||||
_validators: any[];
|
||||
|
||||
/** @internal */
|
||||
_asyncValidators: any[];
|
||||
|
||||
ngOnInit(): void { this.formDirective.addFormGroup(this); }
|
||||
|
||||
ngOnDestroy(): void { this.formDirective.removeFormGroup(this); }
|
||||
|
||||
/**
|
||||
* Get the {@link FormGroup} backing this binding.
|
||||
*/
|
||||
get control(): FormGroup { return this.formDirective.getFormGroup(this); }
|
||||
|
||||
/**
|
||||
* Get the path to this control group.
|
||||
*/
|
||||
get path(): string[] { return controlPath(this.name, this._parent); }
|
||||
|
||||
/**
|
||||
* Get the {@link Form} to which this group belongs.
|
||||
*/
|
||||
get formDirective(): Form { return this._parent.formDirective; }
|
||||
|
||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||
|
||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
import {FormControl, FormGroup} from '../model';
|
||||
|
||||
import {AbstractFormGroupDirective} from './abstract_form_group_directive';
|
||||
import {NgControl} from './ng_control';
|
||||
import {NgControlGroup} from './ng_control_group';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -30,17 +31,17 @@ export interface Form {
|
|||
/**
|
||||
* Add a group of controls to this form.
|
||||
*/
|
||||
addFormGroup(dir: NgControlGroup): void;
|
||||
addFormGroup(dir: AbstractFormGroupDirective): void;
|
||||
|
||||
/**
|
||||
* Remove a group of controls from this form.
|
||||
*/
|
||||
removeFormGroup(dir: NgControlGroup): void;
|
||||
removeFormGroup(dir: AbstractFormGroupDirective): void;
|
||||
|
||||
/**
|
||||
* Look up the {@link FormGroup} associated with a particular {@link NgControlGroup}.
|
||||
* Look up the {@link FormGroup} associated with a particular {@link AbstractFormGroupDirective}.
|
||||
*/
|
||||
getFormGroup(dir: NgControlGroup): FormGroup;
|
||||
getFormGroup(dir: AbstractFormGroupDirective): FormGroup;
|
||||
|
||||
/**
|
||||
* Update the model for a particular control with a new value.
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
import {Directive, Host, Inject, OnDestroy, OnInit, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
||||
|
||||
import {FormGroup} from '../model';
|
||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||
|
||||
import {ControlContainer} from './control_container';
|
||||
import {Form} from './form_interface';
|
||||
import {composeAsyncValidators, composeValidators, controlPath} from './shared';
|
||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||
|
||||
export const controlGroupProvider: any =
|
||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||
provide: ControlContainer,
|
||||
useExisting: forwardRef(() => NgControlGroup)
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates and binds a control group to a DOM element.
|
||||
*
|
||||
* This directive can only be used as a child of {@link NgForm} or {@link FormGroupDirective}.
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* selector: 'my-app',
|
||||
* template: `
|
||||
* <div>
|
||||
* <h2>Angular FormControl & FormGroup Example</h2>
|
||||
* <form #f="ngForm">
|
||||
* <div ngControlGroup="name" #cgName="ngForm">
|
||||
* <h3>Enter your name:</h3>
|
||||
* <p>First: <input name="first" ngModel required></p>
|
||||
* <p>Middle: <input name="middle" ngModel></p>
|
||||
* <p>Last: <input name="last" ngModel required></p>
|
||||
* </div>
|
||||
* <h3>Name value:</h3>
|
||||
* <pre>{{valueOf(cgName)}}</pre>
|
||||
* <p>Name is {{cgName?.control?.valid ? "valid" : "invalid"}}</p>
|
||||
* <h3>What's your favorite food?</h3>
|
||||
* <p><input name="food" ngModel></p>
|
||||
* <h3>Form value</h3>
|
||||
* <pre>{{valueOf(f)}}</pre>
|
||||
* </form>
|
||||
* </div>
|
||||
* `
|
||||
* })
|
||||
* export class App {
|
||||
* valueOf(cg: NgControlGroup): string {
|
||||
* if (cg.control == null) {
|
||||
* return null;
|
||||
* }
|
||||
* return JSON.stringify(cg.control.value, null, 2);
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* This example declares a control group for a user's name. The value and validation state of
|
||||
* this group can be accessed separately from the overall form.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[ngControlGroup]',
|
||||
providers: [controlGroupProvider],
|
||||
inputs: ['name: ngControlGroup'],
|
||||
exportAs: 'ngForm'
|
||||
})
|
||||
export class NgControlGroup extends ControlContainer implements OnInit,
|
||||
OnDestroy {
|
||||
/** @internal */
|
||||
_parent: ControlContainer;
|
||||
|
||||
constructor(
|
||||
@Host() @SkipSelf() parent: ControlContainer,
|
||||
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||
super();
|
||||
this._parent = parent;
|
||||
}
|
||||
|
||||
ngOnInit(): void { this.formDirective.addFormGroup(this); }
|
||||
|
||||
ngOnDestroy(): void { this.formDirective.removeFormGroup(this); }
|
||||
|
||||
/**
|
||||
* Get the {@link FormGroup} backing this binding.
|
||||
*/
|
||||
get control(): FormGroup { return this.formDirective.getFormGroup(this); }
|
||||
|
||||
/**
|
||||
* Get the path to this control group.
|
||||
*/
|
||||
get path(): string[] { return controlPath(this.name, this._parent); }
|
||||
|
||||
/**
|
||||
* Get the {@link Form} to which this group belongs.
|
||||
*/
|
||||
get formDirective(): Form { return this._parent.formDirective; }
|
||||
|
||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||
|
||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||
}
|
|
@ -9,7 +9,7 @@ import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
|||
import {ControlContainer} from './control_container';
|
||||
import {Form} from './form_interface';
|
||||
import {NgControl} from './ng_control';
|
||||
import {NgControlGroup} from './ng_control_group';
|
||||
import {NgModelGroup} from './ng_model_group';
|
||||
import {composeAsyncValidators, composeValidators, setUpControl, setUpFormGroup} from './shared';
|
||||
|
||||
export const formDirectiveProvider: any =
|
||||
|
@ -44,12 +44,12 @@ export const formDirectiveProvider: any =
|
|||
* <h2>NgForm demo</h2>
|
||||
* <form #f="ngForm" (ngSubmit)="onSubmit(f.value)">
|
||||
* <h3>Control group: credentials</h3>
|
||||
* <div ngControlGroup="credentials">
|
||||
* <div ngModelGroup="credentials">
|
||||
* <p>Login: <input type="text" name="login" ngModel></p>
|
||||
* <p>Password: <input type="password" name="password" ngModel></p>
|
||||
* </div>
|
||||
* <h3>Control group: person</h3>
|
||||
* <div ngControlGroup="person">
|
||||
* <div ngModelGroup="person">
|
||||
* <p>First name: <input type="text" name="firstName" ngModel></p>
|
||||
* <p>Last name: <input type="text" name="lastName" ngModel></p>
|
||||
* </div>
|
||||
|
@ -129,7 +129,7 @@ export class NgForm extends ControlContainer implements Form {
|
|||
});
|
||||
}
|
||||
|
||||
addFormGroup(dir: NgControlGroup): void {
|
||||
addFormGroup(dir: NgModelGroup): void {
|
||||
PromiseWrapper.scheduleMicrotask(() => {
|
||||
var container = this._findContainer(dir.path);
|
||||
var group = new FormGroup({});
|
||||
|
@ -139,7 +139,7 @@ export class NgForm extends ControlContainer implements Form {
|
|||
});
|
||||
}
|
||||
|
||||
removeFormGroup(dir: NgControlGroup): void {
|
||||
removeFormGroup(dir: NgModelGroup): void {
|
||||
PromiseWrapper.scheduleMicrotask(() => {
|
||||
var container = this._findContainer(dir.path);
|
||||
if (isPresent(container)) {
|
||||
|
@ -148,7 +148,7 @@ export class NgForm extends ControlContainer implements Form {
|
|||
});
|
||||
}
|
||||
|
||||
getFormGroup(dir: NgControlGroup): FormGroup { return <FormGroup>this.form.find(dir.path); }
|
||||
getFormGroup(dir: NgModelGroup): FormGroup { return <FormGroup>this.form.find(dir.path); }
|
||||
|
||||
updateModel(dir: NgControl, value: any): void {
|
||||
PromiseWrapper.scheduleMicrotask(() => {
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import {Directive, Host, Inject, Input, OnDestroy, OnInit, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
||||
|
||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||
|
||||
import {AbstractFormGroupDirective} from './abstract_form_group_directive';
|
||||
import {ControlContainer} from './control_container';
|
||||
|
||||
export const modelGroupProvider: any =
|
||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||
provide: ControlContainer,
|
||||
useExisting: forwardRef(() => NgModelGroup)
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates and binds a model group to a DOM element.
|
||||
*
|
||||
* This directive can only be used as a child of {@link NgForm}.
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* selector: 'my-app',
|
||||
* template: `
|
||||
* <div>
|
||||
* <h2>Angular forms Example</h2>
|
||||
* <form #f="ngForm">
|
||||
* <div ngModelGroup="name" #mgName="ngModelGroup">
|
||||
* <h3>Enter your name:</h3>
|
||||
* <p>First: <input name="first" ngModel required></p>
|
||||
* <p>Middle: <input name="middle" ngModel></p>
|
||||
* <p>Last: <input name="last" ngModel required></p>
|
||||
* </div>
|
||||
* <h3>Name value:</h3>
|
||||
* <pre>{{ mgName | json }}</pre>
|
||||
* <p>Name is {{mgName?.valid ? "valid" : "invalid"}}</p>
|
||||
* <h3>What's your favorite food?</h3>
|
||||
* <p><input name="food" ngModel></p>
|
||||
* <h3>Form value</h3>
|
||||
* <pre>{{ f | json }}</pre>
|
||||
* </form>
|
||||
* </div>
|
||||
* `
|
||||
* })
|
||||
* export class App {}
|
||||
* ```
|
||||
*
|
||||
* This example declares a model group for a user's name. The value and validation state of
|
||||
* this group can be accessed separately from the overall form.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
@Directive({selector: '[ngModelGroup]', providers: [modelGroupProvider], exportAs: 'ngModelGroup'})
|
||||
export class NgModelGroup extends AbstractFormGroupDirective implements OnInit, OnDestroy {
|
||||
@Input('ngModelGroup') name: string;
|
||||
|
||||
constructor(
|
||||
@Host() @SkipSelf() parent: ControlContainer,
|
||||
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
||||
super();
|
||||
this._parent = parent;
|
||||
this._validators = validators;
|
||||
this._asyncValidators = asyncValidators;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
import {Directive, Host, Inject, Input, OnChanges, OnDestroy, Optional, Output, Self, SimpleChanges, SkipSelf, forwardRef} from '@angular/core';
|
||||
|
||||
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||
import {FormControl} from '../model';
|
||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||
import {EventEmitter, ObservableWrapper} from '../../../facade/async';
|
||||
import {FormControl} from '../../model';
|
||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';
|
||||
|
||||
import {ControlContainer} from './control_container';
|
||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||
import {NgControl} from './ng_control';
|
||||
import {composeAsyncValidators, composeValidators, controlPath, isPropertyUpdated, selectValueAccessor} from './shared';
|
||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||
import {ControlContainer} from '../control_container';
|
||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '../control_value_accessor';
|
||||
import {NgControl} from '../ng_control';
|
||||
import {composeAsyncValidators, composeValidators, controlPath, isPropertyUpdated, selectValueAccessor} from '../shared';
|
||||
import {AsyncValidatorFn, ValidatorFn} from '../validators';
|
||||
|
||||
|
||||
export const controlNameBinding: any =
|
||||
|
@ -18,9 +18,9 @@ export const controlNameBinding: any =
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates and binds a form control with a specified name to a DOM element.
|
||||
* Syncs an existing form control with the specified name to a DOM element.
|
||||
*
|
||||
* This directive can only be used as a child of {@link NgForm} or {@link FormGroupDirective}.
|
||||
* This directive can only be used as a child of {@link FormGroupDirective}.
|
||||
|
||||
* ### Example
|
||||
*
|
|
@ -6,13 +6,13 @@ import {BaseException} from '../../../facade/exceptions';
|
|||
import {isBlank} from '../../../facade/lang';
|
||||
import {FormControl, FormGroup} from '../../model';
|
||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from '../../validators';
|
||||
|
||||
import {ControlContainer} from '../control_container';
|
||||
import {Form} from '../form_interface';
|
||||
import {NgControl} from '../ng_control';
|
||||
import {NgControlGroup} from '../ng_control_group';
|
||||
import {composeAsyncValidators, composeValidators, setUpControl, setUpFormGroup} from '../shared';
|
||||
|
||||
import {FormGroupName} from './form_group_name';
|
||||
|
||||
export const formDirectiveProvider: any =
|
||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||
provide: ControlContainer,
|
||||
|
@ -148,15 +148,15 @@ export class FormGroupDirective extends ControlContainer implements Form,
|
|||
|
||||
removeControl(dir: NgControl): void { ListWrapper.remove(this.directives, dir); }
|
||||
|
||||
addFormGroup(dir: NgControlGroup) {
|
||||
addFormGroup(dir: FormGroupName) {
|
||||
var ctrl: any = this.form.find(dir.path);
|
||||
setUpFormGroup(ctrl, dir);
|
||||
ctrl.updateValueAndValidity({emitEvent: false});
|
||||
}
|
||||
|
||||
removeFormGroup(dir: NgControlGroup) {}
|
||||
removeFormGroup(dir: FormGroupName) {}
|
||||
|
||||
getFormGroup(dir: NgControlGroup): FormGroup { return <FormGroup>this.form.find(dir.path); }
|
||||
getFormGroup(dir: FormGroupName): FormGroup { return <FormGroup>this.form.find(dir.path); }
|
||||
|
||||
updateModel(dir: NgControl, value: any): void {
|
||||
var ctrl = <FormControl>this.form.find(dir.path);
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
import {Directive, Host, Inject, Input, OnDestroy, OnInit, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';
|
||||
import {AbstractFormGroupDirective} from '../abstract_form_group_directive';
|
||||
import {ControlContainer} from '../control_container';
|
||||
|
||||
export const formGroupNameProvider: any =
|
||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||
provide: ControlContainer,
|
||||
useExisting: forwardRef(() => FormGroupName)
|
||||
};
|
||||
|
||||
/**
|
||||
* Syncs an existing form group to a DOM element.
|
||||
*
|
||||
* This directive can only be used as a child of {@link FormGroupDirective}.
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* selector: 'my-app',
|
||||
* template: `
|
||||
* <div>
|
||||
* <h2>Angular FormGroup Example</h2>
|
||||
* <form [formGroup]="myForm">
|
||||
* <div formGroupName="name">
|
||||
* <h3>Enter your name:</h3>
|
||||
* <p>First: <input formControlName="first"></p>
|
||||
* <p>Middle: <input formControlName="middle"></p>
|
||||
* <p>Last: <input formControlName="last"></p>
|
||||
* </div>
|
||||
* <h3>Name value:</h3>
|
||||
* <pre>{{ nameGroup | json }}</pre>
|
||||
* <p>Name is {{nameGroup?.valid ? "valid" : "invalid"}}</p>
|
||||
* <h3>What's your favorite food?</h3>
|
||||
* <p><input formControlName="food"></p>
|
||||
* <h3>Form value</h3>
|
||||
* <pre> {{ myForm | json }} </pre>
|
||||
* </form>
|
||||
* </div>
|
||||
* `
|
||||
* })
|
||||
* export class App {
|
||||
* nameGroup = new FormGroup({
|
||||
* first: new FormControl('', Validators.required),
|
||||
* middle: new FormControl(''),
|
||||
* last: new FormControl('', Validators.required)
|
||||
* });
|
||||
*
|
||||
* myForm = new FormGroup({
|
||||
* name: this.nameGroup,
|
||||
* food: new FormControl()
|
||||
* });
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* This example syncs the form group for the user's name. The value and validation state of
|
||||
* this group can be accessed separately from the overall form.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
@Directive({selector: '[formGroupName]', providers: [formGroupNameProvider]})
|
||||
export class FormGroupName extends AbstractFormGroupDirective implements OnInit, OnDestroy {
|
||||
@Input('formGroupName') name: string;
|
||||
|
||||
constructor(
|
||||
@Host() @SkipSelf() parent: ControlContainer,
|
||||
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
||||
super();
|
||||
this._parent = parent;
|
||||
this._validators = validators;
|
||||
this._asyncValidators = asyncValidators;
|
||||
}
|
||||
}
|
|
@ -5,12 +5,12 @@ import {FormControl, FormGroup} from '../model';
|
|||
import {Validators} from '../validators';
|
||||
|
||||
import {AbstractControlDirective} from './abstract_control_directive';
|
||||
import {AbstractFormGroupDirective} from './abstract_form_group_directive';
|
||||
import {CheckboxControlValueAccessor} from './checkbox_value_accessor';
|
||||
import {ControlContainer} from './control_container';
|
||||
import {ControlValueAccessor} from './control_value_accessor';
|
||||
import {DefaultValueAccessor} from './default_value_accessor';
|
||||
import {NgControl} from './ng_control';
|
||||
import {NgControlGroup} from './ng_control_group';
|
||||
import {normalizeAsyncValidator, normalizeValidator} from './normalize_validator';
|
||||
import {NumberValueAccessor} from './number_value_accessor';
|
||||
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
||||
|
@ -46,7 +46,7 @@ export function setUpControl(control: FormControl, dir: NgControl): void {
|
|||
dir.valueAccessor.registerOnTouched(() => control.markAsTouched());
|
||||
}
|
||||
|
||||
export function setUpFormGroup(control: FormGroup, dir: NgControlGroup) {
|
||||
export function setUpFormGroup(control: FormGroup, dir: AbstractFormGroupDirective) {
|
||||
if (isBlank(control)) _throwError(dir, 'Cannot find control');
|
||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||
|
|
|
@ -17,7 +17,7 @@ import * as modelModule from './model';
|
|||
* template: `
|
||||
* <form [formGroup]="loginForm">
|
||||
* <p>Login <input formControlName="login"></p>
|
||||
* <div ngControlGroup="passwordRetry">
|
||||
* <div formGroupName="passwordRetry">
|
||||
* <p>Password <input type="password" formControlName="password"></p>
|
||||
* <p>Confirm password <input type="password" formControlName="passwordConfirmation"></p>
|
||||
* </div>
|
||||
|
|
|
@ -4,8 +4,7 @@ import {fakeAsync, flushMicrotasks, Log, tick,} from '@angular/core/testing';
|
|||
|
||||
import {SpyNgControl, SpyValueAccessor} from '../spies';
|
||||
|
||||
import {FormGroup, FormControl, FormControlName, NgControlGroup, FormGroupDirective, ControlValueAccessor, Validators, NgForm, NgModel, FormControlDirective, NgControl, DefaultValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, Validator} from '@angular/common/src/forms';
|
||||
|
||||
import {FormGroup, FormControl, FormControlName, FormGroupName, NgModelGroup, FormGroupDirective, ControlValueAccessor, Validators, NgForm, NgModel, FormControlDirective, NgControl, DefaultValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, Validator} from '@angular/common/src/forms';
|
||||
|
||||
import {selectValueAccessor, composeValidators} from '@angular/common/src/forms/directives/shared';
|
||||
import {TimerWrapper} from '../../src/facade/async';
|
||||
|
@ -195,7 +194,7 @@ export function main() {
|
|||
};
|
||||
|
||||
it('should set up validator', fakeAsync(() => {
|
||||
var group = new NgControlGroup(
|
||||
var group = new FormGroupName(
|
||||
form, [matchingPasswordsValidator], [asyncValidator('expected')]);
|
||||
group.name = 'passwords';
|
||||
form.addFormGroup(group);
|
||||
|
@ -271,7 +270,7 @@ export function main() {
|
|||
form = new NgForm([], []);
|
||||
formModel = form.form;
|
||||
|
||||
personControlGroupDir = new NgControlGroup(form, [], []);
|
||||
personControlGroupDir = new NgModelGroup(form, [], []);
|
||||
personControlGroupDir.name = 'person';
|
||||
|
||||
loginControlDir = new FormControlName(personControlGroupDir, null, null, [defaultAccessor]);
|
||||
|
@ -338,7 +337,7 @@ export function main() {
|
|||
}));
|
||||
});
|
||||
|
||||
describe('NgControlGroup', () => {
|
||||
describe('FormGroupName', () => {
|
||||
var formModel: any /** TODO #9100 */;
|
||||
var controlGroupDir: any /** TODO #9100 */;
|
||||
|
||||
|
@ -347,7 +346,7 @@ export function main() {
|
|||
|
||||
var parent = new FormGroupDirective([], []);
|
||||
parent.form = new FormGroup({'group': formModel});
|
||||
controlGroupDir = new NgControlGroup(parent, [], []);
|
||||
controlGroupDir = new FormGroupName(parent, [], []);
|
||||
controlGroupDir.name = 'group';
|
||||
});
|
||||
|
||||
|
|
|
@ -991,7 +991,7 @@ export function main() {
|
|||
new FormGroup({'nested': new FormGroup({'login': new FormControl('value')})});
|
||||
|
||||
const t = `<div [formGroup]="form">
|
||||
<div ngControlGroup="nested">
|
||||
<div formGroupName="nested">
|
||||
<input type="text" formControlName="login">
|
||||
</div>
|
||||
</div>`;
|
||||
|
@ -1014,7 +1014,7 @@ export function main() {
|
|||
new FormGroup({'nested': new FormGroup({'login': new FormControl('value')})});
|
||||
|
||||
const t = `<div [formGroup]="form">
|
||||
<div ngControlGroup="nested">
|
||||
<div formGroupName="nested">
|
||||
<input type="text" formControlName="login">
|
||||
</div>
|
||||
</div>`;
|
||||
|
@ -1083,8 +1083,8 @@ export function main() {
|
|||
it('should add new controls and control groups',
|
||||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
const t = `<form>
|
||||
<div ngControlGroup="user">
|
||||
<input type="text" formControlName="login">
|
||||
<div ngModelGroup="user">
|
||||
<input type="text" name="login" ngModel>
|
||||
</div>
|
||||
</form>`;
|
||||
|
||||
|
@ -1137,7 +1137,7 @@ export function main() {
|
|||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
const t = `<form>
|
||||
<div *ngIf="name == 'show'">
|
||||
<input type="text" formControlName="login">
|
||||
<input type="text" name="login" ngModel>
|
||||
</div>
|
||||
</form>`;
|
||||
|
||||
|
@ -1161,7 +1161,7 @@ export function main() {
|
|||
it('should remove control groups',
|
||||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
const t = `<form>
|
||||
<div *ngIf="name=='show'" ngControlGroup="user">
|
||||
<div *ngIf="name=='show'" ngModelGroup="user">
|
||||
<input type="text" name="login" ngModel>
|
||||
</div>
|
||||
</form>`;
|
||||
|
@ -1492,7 +1492,7 @@ export function main() {
|
|||
// {{x.valid}} used to crash because valid() tried to read a property
|
||||
// from form.control before it was set. This test verifies this bug is
|
||||
// fixed.
|
||||
const t = `<form><div ngControlGroup="x" #x="ngForm">
|
||||
const t = `<form><div ngModelGroup="x" #x="ngModelGroup">
|
||||
<input type="text" name="test" ngModel></div>{{x.valid}}</form>`;
|
||||
let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
|
||||
tick();
|
||||
|
|
Loading…
Reference in New Issue