parent
							
								
									73351ac00f
								
							
						
					
					
						commit
						d6cda15879
					
				| @ -40,7 +40,7 @@ export class CheckboxControlValueAccessor implements ControlValueAccessor { | ||||
|     cd.valueAccessor = this; | ||||
|   } | ||||
| 
 | ||||
|   writeValue(value: any) { setProperty(this._renderer, this._elementRef, "checked", value); } | ||||
|   writeValue(value: any): void { setProperty(this._renderer, this._elementRef, "checked", value); } | ||||
| 
 | ||||
|   get ngClassUntouched(): boolean { | ||||
|     return isPresent(this._cd.control) ? this._cd.control.untouched : false; | ||||
|  | ||||
| @ -2,7 +2,7 @@ import {Form} from './form_interface'; | ||||
| import {AbstractControlDirective} from './abstract_control_directive'; | ||||
| 
 | ||||
| /** | ||||
|  * A directive that contains a group of [NgControl]. | ||||
|  * A directive that contains multiple {@link NgControl}. | ||||
|  * | ||||
|  * Only used by the forms module. | ||||
|  */ | ||||
|  | ||||
| @ -41,9 +41,7 @@ export class DefaultValueAccessor implements ControlValueAccessor { | ||||
|     cd.valueAccessor = this; | ||||
|   } | ||||
| 
 | ||||
|   writeValue(value: any) { | ||||
|     // both this.value and setProperty are required at the moment
 | ||||
|     // remove when a proper imperative API is provided
 | ||||
|   writeValue(value: any): void { | ||||
|     var normalizedValue = isBlank(value) ? '' : value; | ||||
|     setProperty(this._renderer, this._elementRef, 'value', normalizedValue); | ||||
|   } | ||||
|  | ||||
| @ -42,7 +42,8 @@ const controlGroupBinding = | ||||
|  *      `})
 | ||||
|  * class SignupComp { | ||||
|  *  onSignUp(value) { | ||||
|  *    // value === {personal: {name: 'some name'},
 | ||||
|  *    // value === {
 | ||||
|  *    //  personal: {name: 'some name'},
 | ||||
|  *    //  credentials: {login: 'some login', password: 'some password'}}
 | ||||
|  *  } | ||||
|  * } | ||||
| @ -63,9 +64,9 @@ export class NgControlGroup extends ControlContainer implements OnInit, | ||||
|     this._parent = _parent; | ||||
|   } | ||||
| 
 | ||||
|   onInit() { this.formDirective.addControlGroup(this); } | ||||
|   onInit(): void { this.formDirective.addControlGroup(this); } | ||||
| 
 | ||||
|   onDestroy() { this.formDirective.removeControlGroup(this); } | ||||
|   onDestroy(): void { this.formDirective.removeControlGroup(this); } | ||||
| 
 | ||||
|   get control(): ControlGroup { return this.formDirective.getControlGroup(this); } | ||||
| 
 | ||||
|  | ||||
| @ -24,7 +24,7 @@ const controlNameBinding = | ||||
|  * | ||||
|  * In this example, we create the login and password controls. | ||||
|  * We can work with each control separately: check its validity, get its value, listen to its | ||||
|  changes. | ||||
|  * changes. | ||||
|  * | ||||
|  *  ``` | ||||
|  * @Component({selector: "login-comp"}) | ||||
| @ -36,12 +36,11 @@ const controlNameBinding = | ||||
|  *          <div *ng-if="!l.valid">Login is invalid</div> | ||||
|  * | ||||
|  *          Password <input type='password' ng-control='password'> | ||||
| 
 | ||||
|  *          <button type='submit'>Log in!</button> | ||||
|  *        </form> | ||||
|  *      `})
 | ||||
|  * class LoginComp { | ||||
|  *  onLogIn(value) { | ||||
|  *  onLogIn(value): void { | ||||
|  *    // value === {login: 'some login', password: 'some password'}
 | ||||
|  *  } | ||||
|  * } | ||||
| @ -57,14 +56,14 @@ const controlNameBinding = | ||||
|  *        <form (submit)='onLogIn()'> | ||||
|  *          Login <input type='text' ng-control='login' [(ng-model)]="credentials.login"> | ||||
|  *          Password <input type='password' ng-control='password' | ||||
|  [(ng-model)]="credentials.password"> | ||||
|  *                          [(ng-model)]="credentials.password"> | ||||
|  *          <button type='submit'>Log in!</button> | ||||
|  *        </form> | ||||
|  *      `})
 | ||||
|  * class LoginComp { | ||||
|  *  credentials: {login:string, password:string}; | ||||
|  * | ||||
|  *  onLogIn() { | ||||
|  *  onLogIn(): void { | ||||
|  *    // this.credentials.login === "some login"
 | ||||
|  *    // this.credentials.password === "some password"
 | ||||
|  *  } | ||||
| @ -94,18 +93,18 @@ export class NgControlName extends NgControl implements OnChanges, | ||||
|     this.validators = validators; | ||||
|   } | ||||
| 
 | ||||
|   onChanges(c: StringMap<string, any>) { | ||||
|   onChanges(changes: StringMap<string, any>) { | ||||
|     if (!this._added) { | ||||
|       this.formDirective.addControl(this); | ||||
|       this._added = true; | ||||
|     } | ||||
|     if (isPropertyUpdated(c, this.viewModel)) { | ||||
|     if (isPropertyUpdated(changes, this.viewModel)) { | ||||
|       this.viewModel = this.model; | ||||
|       this.formDirective.updateModel(this, this.model); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   onDestroy() { this.formDirective.removeControl(this); } | ||||
|   onDestroy(): void { this.formDirective.removeControl(this); } | ||||
| 
 | ||||
|   viewToModelUpdate(newValue: any): void { | ||||
|     this.viewModel = newValue; | ||||
|  | ||||
| @ -42,8 +42,9 @@ const formDirectiveBinding = | ||||
|  *              </form> | ||||
|  *      `})
 | ||||
|  * class SignupComp { | ||||
|  *  onSignUp(value) { | ||||
|  *    // value === {personal: {name: 'some name'},
 | ||||
|  *  onSignUp(value): void { | ||||
|  *    // value === {
 | ||||
|  *    //  personal: {name: 'some name'},
 | ||||
|  *    //  credentials: {login: 'some login', password: 'some password'}}
 | ||||
|  *  } | ||||
|  * } | ||||
| @ -60,14 +61,9 @@ const formDirectiveBinding = | ||||
|   exportAs: 'form' | ||||
| }) | ||||
| export class NgForm extends ControlContainer implements Form { | ||||
|   form: ControlGroup; | ||||
|   form: ControlGroup = new ControlGroup({}); | ||||
|   ngSubmit = new EventEmitter(); | ||||
| 
 | ||||
|   constructor() { | ||||
|     super(); | ||||
|     this.form = new ControlGroup({}); | ||||
|   } | ||||
| 
 | ||||
|   get formDirective(): Form { return this; } | ||||
| 
 | ||||
|   get control(): ControlGroup { return this.form; } | ||||
| @ -79,10 +75,10 @@ export class NgForm extends ControlContainer implements Form { | ||||
|   addControl(dir: NgControl): void { | ||||
|     this._later(_ => { | ||||
|       var container = this._findContainer(dir.path); | ||||
|       var c = new Control(); | ||||
|       setUpControl(c, dir); | ||||
|       container.addControl(dir.name, c); | ||||
|       c.updateValidity(); | ||||
|       var ctrl = new Control(); | ||||
|       setUpControl(ctrl, dir); | ||||
|       container.addControl(dir.name, ctrl); | ||||
|       ctrl.updateValidity(); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| @ -101,9 +97,9 @@ export class NgForm extends ControlContainer implements Form { | ||||
|   addControlGroup(dir: NgControlGroup): void { | ||||
|     this._later(_ => { | ||||
|       var container = this._findContainer(dir.path); | ||||
|       var c = new ControlGroup({}); | ||||
|       container.addControl(dir.name, c); | ||||
|       c.updateValidity(); | ||||
|       var group = new ControlGroup({}); | ||||
|       container.addControl(dir.name, group); | ||||
|       group.updateValidity(); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| @ -123,8 +119,8 @@ export class NgForm extends ControlContainer implements Form { | ||||
| 
 | ||||
|   updateModel(dir: NgControl, value: any): void { | ||||
|     this._later(_ => { | ||||
|       var c = <Control>this.form.find(dir.path); | ||||
|       c.updateValue(value); | ||||
|       var ctrl = <Control>this.form.find(dir.path); | ||||
|       ctrl.updateValue(value); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| @ -138,9 +134,5 @@ export class NgForm extends ControlContainer implements Form { | ||||
|     return ListWrapper.isEmpty(path) ? this.form : <ControlGroup>this.form.find(path); | ||||
|   } | ||||
| 
 | ||||
|   _later(fn) { | ||||
|     var c: PromiseCompleter<any> = PromiseWrapper.completer(); | ||||
|     PromiseWrapper.then(c.promise, fn, (_) => {}); | ||||
|     c.resolve(null); | ||||
|   } | ||||
|   _later(fn): void { PromiseWrapper.then(PromiseWrapper.resolve(null), fn, (_) => {}); } | ||||
| } | ||||
|  | ||||
| @ -17,10 +17,8 @@ const formControlBinding = | ||||
|  * # Example | ||||
|  * | ||||
|  * In this example, we bind the control to an input element. When the value of the input element | ||||
|  * changes, the value of | ||||
|  * the control will reflect that change. Likewise, if the value of the control changes, the input | ||||
|  * element reflects that | ||||
|  * change. | ||||
|  * changes, the value of the control will reflect that change. Likewise, if the value of the | ||||
|  * control changes, the input element reflects that change. | ||||
|  * | ||||
|  *  ``` | ||||
|  * @Component({selector: "login-comp"}) | ||||
| @ -29,16 +27,12 @@ const formControlBinding = | ||||
|  *      template: "<input type='text' [ng-form-control]='loginControl'>" | ||||
|  *      }) | ||||
|  * class LoginComp { | ||||
|  *  loginControl:Control; | ||||
|  * | ||||
|  *  constructor() { | ||||
|  *    this.loginControl = new Control(''); | ||||
|  *  } | ||||
|  *  loginControl: Control = new Control('');; | ||||
|  * } | ||||
|  * | ||||
|  *  ``` | ||||
|  * | ||||
|  * We can also use ng-model to bind a domain model to the form. | ||||
|  * We can also use `ng-model` to bind a domain model to the form. | ||||
|  * | ||||
|  *  ``` | ||||
|  * @Component({selector: "login-comp"}) | ||||
| @ -47,12 +41,8 @@ const formControlBinding = | ||||
|  *      template: "<input type='text' [ng-form-control]='loginControl' [(ng-model)]='login'>" | ||||
|  *      }) | ||||
|  * class LoginComp { | ||||
|  *  loginControl:Control; | ||||
|  *  loginControl: Control = new Control(''); | ||||
|  *  login:string; | ||||
|  * | ||||
|  *  constructor() { | ||||
|  *    this.loginControl = new Control(''); | ||||
|  *  } | ||||
|  * } | ||||
|  *  ``` | ||||
|  */ | ||||
| @ -76,13 +66,13 @@ export class NgFormControl extends NgControl implements OnChanges { | ||||
|     this.validators = validators; | ||||
|   } | ||||
| 
 | ||||
|   onChanges(c: StringMap<string, any>) { | ||||
|   onChanges(changes: StringMap<string, any>): void { | ||||
|     if (!this._added) { | ||||
|       setUpControl(this.form, this); | ||||
|       this.form.updateValidity(); | ||||
|       this._added = true; | ||||
|     } | ||||
|     if (isPropertyUpdated(c, this.viewModel)) { | ||||
|     if (isPropertyUpdated(changes, this.viewModel)) { | ||||
|       this.form.updateValue(this.model); | ||||
|       this.viewModel = this.model; | ||||
|     } | ||||
|  | ||||
| @ -21,21 +21,21 @@ const formDirectiveBinding = | ||||
|  * # Example | ||||
|  * | ||||
|  * In this example, we bind the control group to the form element, and we bind the login and | ||||
|  * password controls to the | ||||
|  * login and password elements. | ||||
|  * password controls to the login and password elements. | ||||
|  * | ||||
|  *  ``` | ||||
|  * @Component({selector: "login-comp"}) | ||||
|  * @View({ | ||||
|  *      directives: [FORM_DIRECTIVES], | ||||
|  *      template: "<form [ng-form-model]='loginForm'>" + | ||||
|  *              "Login <input type='text' ng-control='login'>" + | ||||
|  *              "Password <input type='password' ng-control='password'>" + | ||||
|  *              "<button (click)="onLogin()">Login</button>" + | ||||
|  *              "</form>" | ||||
|  *      template: ` | ||||
|  *        <form [ng-form-model]='loginForm'> | ||||
|  *          Login <input type='text' ng-control='login'> | ||||
|  *          Password <input type='password' ng-control='password'> | ||||
|  *          <button (click)="onLogin()">Login</button> | ||||
|  *        </form>` | ||||
|  *      }) | ||||
|  * class LoginComp { | ||||
|  *  loginForm:ControlGroup; | ||||
|  *  loginForm: ControlGroup; | ||||
|  * | ||||
|  *  constructor() { | ||||
|  *    this.loginForm = new ControlGroup({ | ||||
| @ -44,7 +44,7 @@ const formDirectiveBinding = | ||||
|  *    }); | ||||
|  *  } | ||||
|  * | ||||
|  *  onLogin() { | ||||
|  *  onLogin(): void { | ||||
|  *    // this.loginForm.value
 | ||||
|  *  } | ||||
|  * } | ||||
| @ -57,15 +57,17 @@ const formDirectiveBinding = | ||||
|  * @Component({selector: "login-comp"}) | ||||
|  * @View({ | ||||
|  *      directives: [FORM_DIRECTIVES], | ||||
|  *      template: "<form [ng-form-model]='loginForm'>" + | ||||
|  *              "Login <input type='text' ng-control='login' [(ng-model)]='login'>" + | ||||
|  *              "Password <input type='password' ng-control='password' [(ng-model)]='password'>" + | ||||
|  *              "<button (click)="onLogin()">Login</button>" + | ||||
|  *              "</form>" | ||||
|  *      template: ` | ||||
|  *        <form [ng-form-model]='loginForm'> | ||||
|  *          Login <input type='text' ng-control='login' [(ng-model)]='credentials.login'> | ||||
|  *          Password <input type='password' ng-control='password' | ||||
|  *                          [(ng-model)]='credentials.password'> | ||||
|  *          <button (click)="onLogin()">Login</button> | ||||
|  *        </form>` | ||||
|  *      }) | ||||
|  * class LoginComp { | ||||
|  *  credentials:{login:string, password:string} | ||||
|  *  loginForm:ControlGroup; | ||||
|  *  credentials: {login: string, password: string}; | ||||
|  *  loginForm: ControlGroup; | ||||
|  * | ||||
|  *  constructor() { | ||||
|  *    this.loginForm = new ControlGroup({ | ||||
| @ -74,7 +76,7 @@ const formDirectiveBinding = | ||||
|  *    }); | ||||
|  *  } | ||||
|  * | ||||
|  *  onLogin() { | ||||
|  *  onLogin(): void { | ||||
|  *    // this.credentials.login === 'some login'
 | ||||
|  *    // this.credentials.password === 'some password'
 | ||||
|  *  } | ||||
| @ -85,9 +87,7 @@ const formDirectiveBinding = | ||||
|   selector: '[ng-form-model]', | ||||
|   bindings: [formDirectiveBinding], | ||||
|   properties: ['form: ng-form-model'], | ||||
|   host: { | ||||
|     '(submit)': 'onSubmit()', | ||||
|   }, | ||||
|   host: {'(submit)': 'onSubmit()'}, | ||||
|   events: ['ngSubmit'], | ||||
|   exportAs: 'form' | ||||
| }) | ||||
| @ -97,7 +97,7 @@ export class NgFormModel extends ControlContainer implements Form, | ||||
|   directives: NgControl[] = []; | ||||
|   ngSubmit = new EventEmitter(); | ||||
| 
 | ||||
|   onChanges(_) { this._updateDomValue(); } | ||||
|   onChanges(_): void { this._updateDomValue(); } | ||||
| 
 | ||||
|   get formDirective(): Form { return this; } | ||||
| 
 | ||||
| @ -106,9 +106,9 @@ export class NgFormModel extends ControlContainer implements Form, | ||||
|   get path(): string[] { return []; } | ||||
| 
 | ||||
|   addControl(dir: NgControl): void { | ||||
|     var c: any = this.form.find(dir.path); | ||||
|     setUpControl(c, dir); | ||||
|     c.updateValidity(); | ||||
|     var ctrl: any = this.form.find(dir.path); | ||||
|     setUpControl(ctrl, dir); | ||||
|     ctrl.updateValidity(); | ||||
|     this.directives.push(dir); | ||||
|   } | ||||
| 
 | ||||
| @ -125,8 +125,8 @@ export class NgFormModel extends ControlContainer implements Form, | ||||
|   } | ||||
| 
 | ||||
|   updateModel(dir: NgControl, value: any): void { | ||||
|     var c  = <Control>this.form.find(dir.path); | ||||
|     c.updateValue(value); | ||||
|     var ctrl  = <Control>this.form.find(dir.path); | ||||
|     ctrl.updateValue(value); | ||||
|   } | ||||
| 
 | ||||
|   onSubmit(): boolean { | ||||
| @ -136,8 +136,8 @@ export class NgFormModel extends ControlContainer implements Form, | ||||
| 
 | ||||
|   _updateDomValue() { | ||||
|     ListWrapper.forEach(this.directives, dir => { | ||||
|       var c: any = this.form.find(dir.path); | ||||
|       dir.valueAccessor.writeValue(c.value); | ||||
|       var ctrl: any = this.form.find(dir.path); | ||||
|       dir.valueAccessor.writeValue(ctrl.value); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -20,9 +20,8 @@ const formControlBinding = CONST_EXPR(new Binding(NgControl, {toAlias: forwardRe | ||||
|  * @Component({selector: "search-comp"}) | ||||
|  * @View({ | ||||
|  *      directives: [FORM_DIRECTIVES], | ||||
|  *      template: ` | ||||
|               <input type='text' [(ng-model)]="searchQuery"> | ||||
|  *      `})
 | ||||
|  *      template: `<input type='text' [(ng-model)]="searchQuery">` | ||||
|  *      }) | ||||
|  * class SearchComp { | ||||
|  *  searchQuery: string; | ||||
|  * } | ||||
| @ -48,14 +47,14 @@ export class NgModel extends NgControl implements OnChanges { | ||||
|     this.validators = validators; | ||||
|   } | ||||
| 
 | ||||
|   onChanges(c: StringMap<string, any>) { | ||||
|   onChanges(changes: StringMap<string, any>) { | ||||
|     if (!this._added) { | ||||
|       setUpControl(this._control, this); | ||||
|       this._control.updateValidity(); | ||||
|       this._added = true; | ||||
|     } | ||||
| 
 | ||||
|     if (isPropertyUpdated(c, this.viewModel)) { | ||||
|     if (isPropertyUpdated(changes, this.viewModel)) { | ||||
|       this._control.updateValue(this.model); | ||||
|       this.viewModel = this.model; | ||||
|     } | ||||
|  | ||||
| @ -9,7 +9,7 @@ import {isPresent} from 'angular2/src/core/facade/lang'; | ||||
| import {setProperty} from './shared'; | ||||
| 
 | ||||
| /** | ||||
|  * Marks <option> as dynamic, so Angular can be notified when options change. | ||||
|  * Marks `<option>` as dynamic, so Angular can be notified when options change. | ||||
|  * | ||||
|  * #Example: | ||||
|  * | ||||
| @ -53,7 +53,7 @@ export class SelectControlValueAccessor implements ControlValueAccessor { | ||||
|     this._updateValueWhenListOfOptionsChanges(query); | ||||
|   } | ||||
| 
 | ||||
|   writeValue(value: any) { | ||||
|   writeValue(value: any): void { | ||||
|     this.value = value; | ||||
|     setProperty(this._renderer, this._elementRef, "value", value); | ||||
|   } | ||||
|  | ||||
| @ -16,25 +16,25 @@ export function controlPath(name: string, parent: ControlContainer): string[] { | ||||
|   return p; | ||||
| } | ||||
| 
 | ||||
| export function setUpControl(c: Control, dir: NgControl) { | ||||
|   if (isBlank(c)) _throwError(dir, "Cannot find control"); | ||||
| export function setUpControl(control: Control, dir: NgControl): void { | ||||
|   if (isBlank(control)) _throwError(dir, "Cannot find control"); | ||||
|   if (isBlank(dir.valueAccessor)) _throwError(dir, "No value accessor for"); | ||||
| 
 | ||||
|   c.validator = Validators.compose([c.validator, dir.validator]); | ||||
|   dir.valueAccessor.writeValue(c.value); | ||||
|   control.validator = Validators.compose([control.validator, dir.validator]); | ||||
|   dir.valueAccessor.writeValue(control.value); | ||||
| 
 | ||||
|   // view -> model
 | ||||
|   dir.valueAccessor.registerOnChange(newValue => { | ||||
|     dir.viewToModelUpdate(newValue); | ||||
|     c.updateValue(newValue, {emitModelToViewChange: false}); | ||||
|     c.markAsDirty(); | ||||
|     control.updateValue(newValue, {emitModelToViewChange: false}); | ||||
|     control.markAsDirty(); | ||||
|   }); | ||||
| 
 | ||||
|   // model -> view
 | ||||
|   c.registerOnChange(newValue => dir.valueAccessor.writeValue(newValue)); | ||||
|   control.registerOnChange(newValue => dir.valueAccessor.writeValue(newValue)); | ||||
| 
 | ||||
|   // touched
 | ||||
|   dir.valueAccessor.registerOnTouched(() => c.markAsTouched()); | ||||
|   dir.valueAccessor.registerOnTouched(() => control.markAsTouched()); | ||||
| } | ||||
| 
 | ||||
| function _throwError(dir: NgControl, message: string): void { | ||||
|  | ||||
| @ -15,9 +15,7 @@ import * as modelModule from './model'; | ||||
|  * | ||||
|  * @Component({ | ||||
|  *   selector: 'login-comp', | ||||
|  *   viewBindings: [ | ||||
|  *     FormBuilder | ||||
|  *   ] | ||||
|  *   viewBindings: [FormBuilder] | ||||
|  * }) | ||||
|  * @View({ | ||||
|  *   template: ` | ||||
| @ -30,9 +28,7 @@ import * as modelModule from './model'; | ||||
|  *       </div> | ||||
|  *     </form> | ||||
|  *   `,
 | ||||
|  *   directives: [ | ||||
|  *     FORM_DIRECTIVES | ||||
|  *   ] | ||||
|  *   directives: [FORM_DIRECTIVES] | ||||
|  * }) | ||||
|  * class LoginComp { | ||||
|  *   loginForm: ControlGroup; | ||||
| @ -49,12 +45,12 @@ import * as modelModule from './model'; | ||||
|  *   } | ||||
|  * } | ||||
|  * | ||||
|  * bootstrap(LoginComp) | ||||
|  * bootstrap(LoginComp); | ||||
|  * ``` | ||||
|  * | ||||
|  * This example creates a {@link ControlGroup} that consists of a `login` {@link Control}, and a | ||||
|  * nested | ||||
|  * {@link ControlGroup} that defines a `password` and a `passwordConfirmation` {@link Control}: | ||||
|  * nested {@link ControlGroup} that defines a `password` and a `passwordConfirmation` | ||||
|  * {@link Control}: | ||||
|  * | ||||
|  * ``` | ||||
|  *  var loginForm = builder.group({ | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| import {StringWrapper, isPresent, isBlank} from 'angular2/src/core/facade/lang'; | ||||
| import {StringWrapper, isPresent, isBlank, normalizeBool} from 'angular2/src/core/facade/lang'; | ||||
| import {Observable, EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async'; | ||||
| import {StringMap, StringMapWrapper, ListWrapper} from 'angular2/src/core/facade/collection'; | ||||
| import {Validators} from './validators'; | ||||
| @ -13,14 +13,15 @@ export const VALID = "VALID"; | ||||
|  */ | ||||
| export const INVALID = "INVALID"; | ||||
| 
 | ||||
| export function isControl(c: Object): boolean { | ||||
|   return c instanceof AbstractControl; | ||||
| export function isControl(control: Object): boolean { | ||||
|   return control instanceof AbstractControl; | ||||
| } | ||||
| 
 | ||||
| function _find(c: AbstractControl, path: Array<string | number>| string) { | ||||
| function _find(control: AbstractControl, path: Array<string | number>| string) { | ||||
|   if (isBlank(path)) return null; | ||||
| 
 | ||||
|   if (!(path instanceof Array)) { | ||||
|     path = StringWrapper.split(<string>path, new RegExp("/")); | ||||
|     path = (<string>path).split("/"); | ||||
|   } | ||||
|   if (path instanceof Array && ListWrapper.isEmpty(path)) return null; | ||||
| 
 | ||||
| @ -33,7 +34,7 @@ function _find(c: AbstractControl, path: Array<string | number>| string) { | ||||
|     } else { | ||||
|       return null; | ||||
|     } | ||||
|   }, c); | ||||
|   }, control); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -43,18 +44,13 @@ export class AbstractControl { | ||||
|   _value: any; | ||||
|   _status: string; | ||||
|   _errors: StringMap<string, any>; | ||||
|   _pristine: boolean; | ||||
|   _touched: boolean; | ||||
|   _pristine: boolean = true; | ||||
|   _touched: boolean = false; | ||||
|   _parent: ControlGroup | ControlArray; | ||||
|   validator: Function; | ||||
| 
 | ||||
|   _valueChanges: EventEmitter; | ||||
| 
 | ||||
|   constructor(validator: Function) { | ||||
|     this.validator = validator; | ||||
|     this._pristine = true; | ||||
|     this._touched = false; | ||||
|   } | ||||
|   constructor(public validator: Function) {} | ||||
| 
 | ||||
|   get value(): any { return this._value; } | ||||
| 
 | ||||
| @ -77,18 +73,18 @@ export class AbstractControl { | ||||
|   markAsTouched(): void { this._touched = true; } | ||||
| 
 | ||||
|   markAsDirty({onlySelf}: {onlySelf?: boolean} = {}): void { | ||||
|     onlySelf = isPresent(onlySelf) ? onlySelf : false; | ||||
| 
 | ||||
|     onlySelf = normalizeBool(onlySelf); | ||||
|     this._pristine = false; | ||||
| 
 | ||||
|     if (isPresent(this._parent) && !onlySelf) { | ||||
|       this._parent.markAsDirty({onlySelf: onlySelf}); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   setParent(parent: ControlGroup | ControlArray) { this._parent = parent; } | ||||
|   setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; } | ||||
| 
 | ||||
|   updateValidity({onlySelf}: {onlySelf?: boolean} = {}): void { | ||||
|     onlySelf = isPresent(onlySelf) ? onlySelf : false; | ||||
|     onlySelf = normalizeBool(onlySelf); | ||||
| 
 | ||||
|     this._errors = this.validator(this); | ||||
|     this._status = isPresent(this._errors) ? INVALID : VALID; | ||||
| @ -100,7 +96,7 @@ export class AbstractControl { | ||||
| 
 | ||||
|   updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): | ||||
|       void { | ||||
|     onlySelf = isPresent(onlySelf) ? onlySelf : false; | ||||
|     onlySelf = normalizeBool(onlySelf); | ||||
|     emitEvent = isPresent(emitEvent) ? emitEvent : true; | ||||
| 
 | ||||
|     this._updateValue(); | ||||
| @ -111,6 +107,7 @@ export class AbstractControl { | ||||
| 
 | ||||
|     this._errors = this.validator(this); | ||||
|     this._status = isPresent(this._errors) ? INVALID : VALID; | ||||
| 
 | ||||
|     if (isPresent(this._parent) && !onlySelf) { | ||||
|       this._parent.updateValueAndValidity({onlySelf: onlySelf, emitEvent: emitEvent}); | ||||
|     } | ||||
| @ -119,9 +116,9 @@ export class AbstractControl { | ||||
|   find(path: Array<string | number>| string): AbstractControl { return _find(this, path); } | ||||
| 
 | ||||
|   getError(errorCode: string, path: string[] = null): any { | ||||
|     var c = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this; | ||||
|     if (isPresent(c) && isPresent(c._errors)) { | ||||
|       return StringMapWrapper.get(c._errors, errorCode); | ||||
|     var control = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this; | ||||
|     if (isPresent(control) && isPresent(control._errors)) { | ||||
|       return StringMapWrapper.get(control._errors, errorCode); | ||||
|     } else { | ||||
|       return null; | ||||
|     } | ||||
| @ -138,8 +135,7 @@ export class AbstractControl { | ||||
|  * Defines a part of a form that cannot be divided into other controls. | ||||
|  * | ||||
|  * `Control` is one of the three fundamental building blocks used to define forms in Angular, along | ||||
|  * with | ||||
|  * {@link ControlGroup} and {@link ControlArray}. | ||||
|  * with {@link ControlGroup} and {@link ControlArray}. | ||||
|  */ | ||||
| export class Control extends AbstractControl { | ||||
|   _onChange: Function; | ||||
| @ -167,29 +163,22 @@ export class Control extends AbstractControl { | ||||
| /** | ||||
|  * Defines a part of a form, of fixed length, that can contain other controls. | ||||
|  * | ||||
|  * A ControlGroup aggregates the values and errors of each {@link Control} in the group. Thus, if | ||||
|  * one of the controls | ||||
|  * in a group is invalid, the entire group is invalid. Similarly, if a control changes its value, | ||||
|  * the entire group | ||||
|  * changes as well. | ||||
|  * A `ControlGroup` aggregates the values and errors of each {@link Control} in the group. Thus, if | ||||
|  * one of the controls in a group is invalid, the entire group is invalid. Similarly, if a control | ||||
|  * changes its value, the entire group changes as well. | ||||
|  * | ||||
|  * `ControlGroup` is one of the three fundamental building blocks used to define forms in Angular, | ||||
|  * along with | ||||
|  * {@link Control} and {@link ControlArray}. {@link ControlArray} can also contain other controls, | ||||
|  * but is of variable | ||||
|  * length. | ||||
|  * along with {@link Control} and {@link ControlArray}. {@link ControlArray} can also contain other | ||||
|  * controls, but is of variable length. | ||||
|  */ | ||||
| export class ControlGroup extends AbstractControl { | ||||
|   controls: StringMap<string, AbstractControl>; | ||||
|   _optionals: StringMap<string, boolean>; | ||||
|   private _optionals: StringMap<string, boolean>; | ||||
| 
 | ||||
|   constructor(controls: StringMap<string, AbstractControl>, | ||||
|   constructor(public controls: StringMap<string, AbstractControl>, | ||||
|               optionals: StringMap<string, boolean> = null, | ||||
|               validator: Function = Validators.group) { | ||||
|     super(validator); | ||||
|     this.controls = controls; | ||||
|     this._optionals = isPresent(optionals) ? optionals : {}; | ||||
| 
 | ||||
|     this._valueChanges = new EventEmitter(); | ||||
| 
 | ||||
|     this._setParentForControls(); | ||||
| @ -197,12 +186,12 @@ export class ControlGroup extends AbstractControl { | ||||
|     this.updateValidity({onlySelf: true}); | ||||
|   } | ||||
| 
 | ||||
|   addControl(name: string, c: AbstractControl) { | ||||
|     this.controls[name] = c; | ||||
|     c.setParent(this); | ||||
|   addControl(name: string, control: AbstractControl): void { | ||||
|     this.controls[name] = control; | ||||
|     control.setParent(this); | ||||
|   } | ||||
| 
 | ||||
|   removeControl(name: string) { StringMapWrapper.delete(this.controls, name); } | ||||
|   removeControl(name: string): void { StringMapWrapper.delete(this.controls, name); } | ||||
| 
 | ||||
|   include(controlName: string): void { | ||||
|     StringMapWrapper.set(this._optionals, controlName, true); | ||||
| @ -252,21 +241,16 @@ export class ControlGroup extends AbstractControl { | ||||
|  * Defines a part of a form, of variable length, that can contain other controls. | ||||
|  * | ||||
|  * A `ControlArray` aggregates the values and errors of each {@link Control} in the group. Thus, if | ||||
|  * one of the controls | ||||
|  * in a group is invalid, the entire group is invalid. Similarly, if a control changes its value, | ||||
|  * the entire group | ||||
|  * changes as well. | ||||
|  * one of the controls in a group is invalid, the entire group is invalid. Similarly, if a control | ||||
|  * changes its value, the entire group changes as well. | ||||
|  * | ||||
|  * `ControlArray` is one of the three fundamental building blocks used to define forms in Angular, | ||||
|  * along with {@link Control} and {@link ControlGroup}. {@link ControlGroup} can also contain | ||||
|  * other controls, but is of fixed length. | ||||
|  */ | ||||
| export class ControlArray extends AbstractControl { | ||||
|   controls: AbstractControl[]; | ||||
| 
 | ||||
|   constructor(controls: AbstractControl[], validator: Function = Validators.array) { | ||||
|   constructor(public controls: AbstractControl[], validator: Function = Validators.array) { | ||||
|     super(validator); | ||||
|     this.controls = controls; | ||||
| 
 | ||||
|     this._valueChanges = new EventEmitter(); | ||||
| 
 | ||||
| @ -296,9 +280,9 @@ export class ControlArray extends AbstractControl { | ||||
| 
 | ||||
|   get length(): number { return this.controls.length; } | ||||
| 
 | ||||
|   _updateValue() { this._value = ListWrapper.map(this.controls, (c) => c.value); } | ||||
|   _updateValue(): void { this._value = this.controls.map((control) => control.value); } | ||||
| 
 | ||||
|   _setParentForControls() { | ||||
|     ListWrapper.forEach(this.controls, (control) => { control.setParent(this); }); | ||||
|   _setParentForControls(): void { | ||||
|     this.controls.forEach((control) => { control.setParent(this); }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -17,8 +17,8 @@ export const NG_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken("NgValidato | ||||
|  * ``` | ||||
|  */ | ||||
| export class Validators { | ||||
|   static required(c: modelModule.Control): StringMap<string, boolean> { | ||||
|     return isBlank(c.value) || c.value == "" ? {"required": true} : null; | ||||
|   static required(control: modelModule.Control): StringMap<string, boolean> { | ||||
|     return isBlank(control.value) || control.value == "" ? {"required": true} : null; | ||||
|   } | ||||
| 
 | ||||
|   static nullValidator(c: any): StringMap<string, boolean> { return null; } | ||||
| @ -26,28 +26,28 @@ export class Validators { | ||||
|   static compose(validators: Function[]): Function { | ||||
|     if (isBlank(validators)) return Validators.nullValidator; | ||||
| 
 | ||||
|     return function(c: modelModule.Control) { | ||||
|     return function(control: modelModule.Control) { | ||||
|       var res = ListWrapper.reduce(validators, (res, validator) => { | ||||
|         var errors = validator(c); | ||||
|         var errors = validator(control); | ||||
|         return isPresent(errors) ? StringMapWrapper.merge(res, errors) : res; | ||||
|       }, {}); | ||||
|       return StringMapWrapper.isEmpty(res) ? null : res; | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   static group(c: modelModule.ControlGroup): StringMap<string, boolean> { | ||||
|   static group(group: modelModule.ControlGroup): StringMap<string, boolean> { | ||||
|     var res = {}; | ||||
|     StringMapWrapper.forEach(c.controls, (control, name) => { | ||||
|       if (c.contains(name) && isPresent(control.errors)) { | ||||
|     StringMapWrapper.forEach(group.controls, (control, name) => { | ||||
|       if (group.contains(name) && isPresent(control.errors)) { | ||||
|         Validators._mergeErrors(control, res); | ||||
|       } | ||||
|     }); | ||||
|     return StringMapWrapper.isEmpty(res) ? null : res; | ||||
|   } | ||||
| 
 | ||||
|   static array(c: modelModule.ControlArray): StringMap<string, boolean> { | ||||
|   static array(array: modelModule.ControlArray): StringMap<string, boolean> { | ||||
|     var res = {}; | ||||
|     ListWrapper.forEach(c.controls, (control) => { | ||||
|     array.controls.forEach((control) => { | ||||
|       if (isPresent(control.errors)) { | ||||
|         Validators._mergeErrors(control, res); | ||||
|       } | ||||
|  | ||||
| @ -19,7 +19,7 @@ import {RegExpWrapper, print, isPresent} from 'angular2/src/core/facade/lang'; | ||||
|  * Custom validator. | ||||
|  */ | ||||
| function creditCardValidator(c): StringMap<string, boolean> { | ||||
|   if (isPresent(c.value) && RegExpWrapper.test(new RegExp("^\\d{16}$"), c.value)) { | ||||
|   if (isPresent(c.value) && RegExpWrapper.test(/^\d{16}$/g, c.value)) { | ||||
|     return null; | ||||
|   } else { | ||||
|     return {"invalidCreditCard": true}; | ||||
| @ -55,17 +55,19 @@ class ShowError { | ||||
| 
 | ||||
|   constructor(@Host() formDir: NgFormModel) { this.formDir = formDir; } | ||||
| 
 | ||||
|   get errorMessage() { | ||||
|     var c = this.formDir.form.find(this.controlPath); | ||||
|   get errorMessage(): string { | ||||
|     var control = this.formDir.form.find(this.controlPath); | ||||
|     if (isPresent(control) && control.touched) { | ||||
|       for (var i = 0; i < this.errorTypes.length; ++i) { | ||||
|       if (isPresent(c) && c.touched && c.hasError(this.errorTypes[i])) { | ||||
|         if (control.hasError(this.errorTypes[i])) { | ||||
|           return this._errorMessage(this.errorTypes[i]); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   _errorMessage(code) { | ||||
|   _errorMessage(code: string): string { | ||||
|     var config = {'required': 'is required', 'invalidCreditCard': 'is invalid credit card number'}; | ||||
|     return config[code]; | ||||
|   } | ||||
| @ -148,7 +150,7 @@ class ModelDrivenForms { | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   onSubmit() { | ||||
|   onSubmit(): void { | ||||
|     print("Submitting:"); | ||||
|     print(this.form.value); | ||||
|   } | ||||
|  | ||||
| @ -36,7 +36,7 @@ class CheckoutModel { | ||||
|  * Custom validator. | ||||
|  */ | ||||
| function creditCardValidator(c): StringMap<string, boolean> { | ||||
|   if (isPresent(c.value) && RegExpWrapper.test(new RegExp("^\\d{16}$"), c.value)) { | ||||
|   if (isPresent(c.value) && RegExpWrapper.test(/^\d{16}$/g, c.value)) { | ||||
|     return null; | ||||
|   } else { | ||||
|     return {"invalidCreditCard": true}; | ||||
| @ -79,17 +79,19 @@ class ShowError { | ||||
| 
 | ||||
|   constructor(@Host() formDir: NgForm) { this.formDir = formDir; } | ||||
| 
 | ||||
|   get errorMessage() { | ||||
|     var c = this.formDir.form.find(this.controlPath); | ||||
|   get errorMessage(): string { | ||||
|     var control = this.formDir.form.find(this.controlPath); | ||||
|     if (isPresent(control) && control.touched) { | ||||
|       for (var i = 0; i < this.errorTypes.length; ++i) { | ||||
|       if (isPresent(c) && c.touched && c.hasError(this.errorTypes[i])) { | ||||
|         if (control.hasError(this.errorTypes[i])) { | ||||
|           return this._errorMessage(this.errorTypes[i]); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   _errorMessage(code) { | ||||
|   _errorMessage(code: string): string { | ||||
|     var config = {'required': 'is required', 'invalidCreditCard': 'is invalid credit card number'}; | ||||
|     return config[code]; | ||||
|   } | ||||
| @ -159,7 +161,7 @@ class TemplateDrivenForms { | ||||
|   model = new CheckoutModel(); | ||||
|   countries = ['US', 'Canada']; | ||||
| 
 | ||||
|   onSubmit() { | ||||
|   onSubmit(): void { | ||||
|     print("Submitting:"); | ||||
|     print(this.model); | ||||
|   } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user