diff --git a/modules/angular2/forms.js b/modules/angular2/forms.ts
similarity index 76%
rename from modules/angular2/forms.js
rename to modules/angular2/forms.ts
index 6e84373929..eb525a7868 100644
--- a/modules/angular2/forms.js
+++ b/modules/angular2/forms.ts
@@ -2,11 +2,14 @@
* @module
* @public
* @description
- * This module is used for handling user input, by defining and building a {@link ControlGroup} that consists of
- * {@link Control} objects, and mapping them onto the DOM. {@link Control} objects can then be used to read information
+ * This module is used for handling user input, by defining and building a {@link ControlGroup} that
+ * consists of
+ * {@link Control} objects, and mapping them onto the DOM. {@link Control} objects can then be used
+ * to read information
* from the form DOM elements.
*
- * This module is not included in the `angular2` module; you must import the forms module explicitly.
+ * This module is not included in the `angular2` module; you must import the forms module
+ * explicitly.
*
*/
diff --git a/modules/angular2/src/core/annotations/decorators.dart b/modules/angular2/src/core/annotations/decorators.dart
index ec9f91bd46..676088c9e7 100644
--- a/modules/angular2/src/core/annotations/decorators.dart
+++ b/modules/angular2/src/core/annotations/decorators.dart
@@ -1,3 +1,6 @@
library angular2.core.decorators;
+export '../annotations_impl/annotations.dart';
+export '../annotations_impl/visibility.dart';
+
/* This file is empty because, Dart does not have decorators. */
diff --git a/modules/angular2/src/core/annotations/decorators.ts b/modules/angular2/src/core/annotations/decorators.ts
index f5e80b89e5..1829f79579 100644
--- a/modules/angular2/src/core/annotations/decorators.ts
+++ b/modules/angular2/src/core/annotations/decorators.ts
@@ -1,6 +1,11 @@
import {ComponentAnnotation, DirectiveAnnotation} from './annotations';
import {ViewAnnotation} from './view';
-import {AncestorAnnotation, ParentAnnotation} from './visibility';
+import {
+ SelfAnnotation,
+ ParentAnnotation,
+ AncestorAnnotation,
+ UnboundedAnnotation
+} from './visibility';
import {AttributeAnnotation, QueryAnnotation} from './di';
import {makeDecorator, makeParamDecorator} from '../../util/decorators';
@@ -12,8 +17,10 @@ export var Directive = makeDecorator(DirectiveAnnotation);
export var View = makeDecorator(ViewAnnotation);
/* from visibility */
-export var Ancestor = makeParamDecorator(AncestorAnnotation);
+export var Self = makeParamDecorator(SelfAnnotation);
export var Parent = makeParamDecorator(ParentAnnotation);
+export var Ancestor = makeParamDecorator(AncestorAnnotation);
+export var Unbounded = makeParamDecorator(UnboundedAnnotation);
/* from di */
export var Attribute = makeParamDecorator(AttributeAnnotation);
diff --git a/modules/angular2/src/core/annotations/visibility.ts b/modules/angular2/src/core/annotations/visibility.ts
index 53acffc1fb..eded081cea 100644
--- a/modules/angular2/src/core/annotations/visibility.ts
+++ b/modules/angular2/src/core/annotations/visibility.ts
@@ -1,4 +1,6 @@
export {
+ Self as SelfAnnotation,
Ancestor as AncestorAnnotation,
Parent as ParentAnnotation,
+ Unbounded as UnboundedAnnotation
} from '../annotations_impl/visibility';
diff --git a/modules/angular2/src/core/compiler/directive_resolver.ts b/modules/angular2/src/core/compiler/directive_resolver.ts
index 0879db0738..0517336f84 100644
--- a/modules/angular2/src/core/compiler/directive_resolver.ts
+++ b/modules/angular2/src/core/compiler/directive_resolver.ts
@@ -10,7 +10,6 @@ export class DirectiveResolver {
if (isPresent(annotations)) {
for (var i = 0; i < annotations.length; i++) {
var annotation = annotations[i];
-
if (annotation instanceof Directive) {
return annotation;
}
diff --git a/modules/angular2/src/forms/directives.js b/modules/angular2/src/forms/directives.ts
similarity index 62%
rename from modules/angular2/src/forms/directives.js
rename to modules/angular2/src/forms/directives.ts
index 97df5a9de0..6b8bf05c4a 100644
--- a/modules/angular2/src/forms/directives.js
+++ b/modules/angular2/src/forms/directives.ts
@@ -1,19 +1,20 @@
-import {Directive} from 'angular2/src/core/annotations_impl/annotations';
-import {Ancestor} from 'angular2/src/core/annotations_impl/visibility';
+import {Directive, Ancestor} from 'angular2/src/core/annotations/decorators';
+import {Optional} from 'angular2/src/di/decorators';
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
-import {Optional} from 'angular2/src/di/annotations_impl';
import {Renderer} from 'angular2/src/render/api';
-import {isPresent, isString, CONST_EXPR, isBlank, BaseException} from 'angular2/src/facade/lang';
+import {
+ isPresent,
+ isString,
+ CONST_EXPR,
+ isBlank,
+ BaseException,
+ Type
+} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection';
import {ControlGroup, Control, isControl} from './model';
import {Validators} from './validators';
-//export interface ControlValueAccessor {
-// writeValue(value):void{}
-// set onChange(fn){}
-//}
-
-function _lookupControl(groupDirective:ControlGroupDirective, controlOrName:any):any {
+function _lookupControl(groupDirective: ControlGroupDirective, controlOrName: any): any {
if (isControl(controlOrName)) {
return controlOrName;
}
@@ -31,8 +32,10 @@ function _lookupControl(groupDirective:ControlGroupDirective, controlOrName:any)
return control;
}
+
/**
- * The default accessor for writing a value and listening to changes that is used by a {@link Control} directive.
+ * The default accessor for writing a value and listening to changes that is used by a {@link
+ * Control} directive.
*
* This is the default strategy that Angular uses when no other accessor is applied.
*
@@ -45,143 +48,17 @@ function _lookupControl(groupDirective:ControlGroupDirective, controlOrName:any)
*/
@Directive({
selector: '[control]',
- hostListeners: {
- 'change' : 'onChange($event.target.value)',
- 'input' : 'onChange($event.target.value)'
- },
- hostProperties: {
- 'value' : 'value'
- }
+ hostListeners:
+ {'change': 'onChange($event.target.value)', 'input': 'onChange($event.target.value)'},
+ hostProperties: {'value': 'value'}
})
export class DefaultValueAccessor {
value;
- onChange:Function;
+ onChange: Function;
- constructor() {
- this.onChange = (_) => {};
- }
+ constructor() { this.onChange = (_) => {}; }
- writeValue(value) {
- this.value = value
- }
-}
-
-/**
- * The accessor for writing a value and listening to changes on a checkbox input element.
- *
- *
- * # Example
- * ```
- *
- * ```
- *
- * @exportedAs angular2/forms
- */
-@Directive({
- selector: 'input[type=checkbox][control]',
- hostListeners: {
- 'change' : 'onChange($event.target.checked)'
- },
- hostProperties: {
- 'checked' : 'checked'
- }
-})
-export class CheckboxControlValueAccessor {
- _elementRef:ElementRef;
- _renderer:Renderer;
-
- checked:boolean;
- onChange:Function;
-
- constructor(cd:ControlDirective, elementRef:ElementRef, renderer:Renderer) {
- this.onChange = (_) => {};
- this._elementRef = elementRef;
- this._renderer = renderer;
- cd.valueAccessor = this; //ControlDirective should inject CheckboxControlDirective
- }
-
- writeValue(value) {
- this._renderer.setElementProperty(this._elementRef.parentView.render, this._elementRef.boundElementIndex,
- 'checked', value)
- }
-}
-
-/**
- * Binds a control to a DOM element.
- *
- * # 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.
- *
- * Here we use {@link formDirectives}, rather than importing each form directive individually, e.g.
- * `ControlDirective`, `ControlGroupDirective`. This is just a shorthand for the same end result.
- *
- * ```
- * @Component({selector: "login-comp"})
- * @View({
- * directives: [formDirectives],
- * inline: ""
- * })
- * class LoginComp {
- * loginControl:Control;
- *
- * constructor() {
- * this.loginControl = new Control('');
- * }
- * }
- *
- * ```
- *
- * @exportedAs angular2/forms
- */
-@Directive({
- selector: '[control]',
- properties: {
- 'controlOrName' : 'control'
- }
-})
-export class ControlDirective {
- _groupDirective:ControlGroupDirective;
-
- _controlOrName:any;
- valueAccessor:any; //ControlValueAccessor
-
- validator:Function;
-
- constructor(@Optional() @Ancestor() groupDirective:ControlGroupDirective, valueAccessor:DefaultValueAccessor) {
- this._groupDirective = groupDirective;
- this._controlOrName = null;
- this.valueAccessor = valueAccessor;
- this.validator = Validators.nullValidator;
- }
-
- set controlOrName(controlOrName) {
- this._controlOrName = controlOrName;
-
- if(isPresent(this._groupDirective)) {
- this._groupDirective.addDirective(this);
- }
-
- var c = this._control();
- c.validator = Validators.compose([c.validator, this.validator]);
-
- this._updateDomValue();
- this._setUpUpdateControlValue();
- }
-
- _updateDomValue() {
- this.valueAccessor.writeValue(this._control().value);
- }
-
- _setUpUpdateControlValue() {
- this.valueAccessor.onChange = (newValue) => this._control().updateValue(newValue);
- }
-
- _control() {
- return _lookupControl(this._groupDirective, this._controlOrName);
- }
+ writeValue(value) { this.value = value }
}
/**
@@ -189,7 +66,8 @@ export class ControlDirective {
*
* # Example
*
- * In this example, we bind the control group to the form element, and we bind the login and password controls to the
+ * 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.
*
* Here we use {@link formDirectives}, rather than importing each form directive individually, e.g.
@@ -224,18 +102,13 @@ export class ControlDirective {
*
* @exportedAs angular2/forms
*/
-@Directive({
- selector: '[control-group]',
- properties: {
- 'controlOrName' : 'control-group'
- }
-})
+@Directive({selector: '[control-group]', properties: {'controlOrName': 'control-group'}})
export class ControlGroupDirective {
- _groupDirective:ControlGroupDirective;
- _directives:List;
- _controlOrName:any;
+ _groupDirective: ControlGroupDirective;
+ _directives: List;
+ _controlOrName: any;
- constructor(@Optional() @Ancestor() groupDirective:ControlGroupDirective) {
+ constructor(@Optional() @Ancestor() groupDirective: ControlGroupDirective) {
this._groupDirective = groupDirective;
this._directives = ListWrapper.create();
}
@@ -245,23 +118,126 @@ export class ControlGroupDirective {
this._updateDomValue();
}
- _updateDomValue() {
- ListWrapper.forEach(this._directives, (cd) => cd._updateDomValue());
- }
+ _updateDomValue() { ListWrapper.forEach(this._directives, (cd) => cd._updateDomValue()); }
- addDirective(c:ControlDirective) {
- ListWrapper.push(this._directives, c);
- }
+ addDirective(c: ControlDirective) { ListWrapper.push(this._directives, c); }
- findControl(name:string):any {
- return this._getControlGroup().controls[name];
- }
+ findControl(name: string): any { return this._getControlGroup().controls[name]; }
- _getControlGroup():ControlGroup {
+ _getControlGroup(): ControlGroup {
return _lookupControl(this._groupDirective, this._controlOrName);
}
}
+
+/**
+ * Binds a control to a DOM element.
+ *
+ * # 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.
+ *
+ * Here we use {@link formDirectives}, rather than importing each form directive individually, e.g.
+ * `ControlDirective`, `ControlGroupDirective`. This is just a shorthand for the same end result.
+ *
+ * ```
+ * @Component({selector: "login-comp"})
+ * @View({
+ * directives: [formDirectives],
+ * inline: ""
+ * })
+ * class LoginComp {
+ * loginControl:Control;
+ *
+ * constructor() {
+ * this.loginControl = new Control('');
+ * }
+ * }
+ *
+ * ```
+ *
+ * @exportedAs angular2/forms
+ */
+@Directive({selector: '[control]', properties: {'controlOrName': 'control'}})
+export class ControlDirective {
+ _groupDirective: ControlGroupDirective;
+
+ _controlOrName: any;
+ valueAccessor: any; // ControlValueAccessor
+
+ validator: Function;
+
+ constructor(@Optional() @Ancestor() groupDirective: ControlGroupDirective,
+ valueAccessor: DefaultValueAccessor) {
+ this._groupDirective = groupDirective;
+ this._controlOrName = null;
+ this.valueAccessor = valueAccessor;
+ this.validator = Validators.nullValidator;
+ }
+
+ set controlOrName(controlOrName) {
+ this._controlOrName = controlOrName;
+
+ if (isPresent(this._groupDirective)) {
+ this._groupDirective.addDirective(this);
+ }
+
+ var c = this._control();
+ c.validator = Validators.compose([c.validator, this.validator]);
+
+ this._updateDomValue();
+ this._setUpUpdateControlValue();
+ }
+
+ _updateDomValue() { this.valueAccessor.writeValue(this._control().value); }
+
+ _setUpUpdateControlValue() {
+ this.valueAccessor.onChange = (newValue) => this._control().updateValue(newValue);
+ }
+
+ _control() { return _lookupControl(this._groupDirective, this._controlOrName); }
+}
+
+/**
+ * The accessor for writing a value and listening to changes on a checkbox input element.
+ *
+ *
+ * # Example
+ * ```
+ *
+ * ```
+ *
+ * @exportedAs angular2/forms
+ */
+@Directive({
+ selector: 'input[type=checkbox][control]',
+ hostListeners: {'change': 'onChange($event.target.checked)'},
+ hostProperties: {'checked': 'checked'}
+})
+export class CheckboxControlValueAccessor {
+ _elementRef: ElementRef;
+ _renderer: Renderer;
+
+ checked: boolean;
+ onChange: Function;
+
+ constructor(cd: ControlDirective, elementRef: ElementRef, renderer: Renderer) {
+ this.onChange = (_) => {};
+ this._elementRef = elementRef;
+ this._renderer = renderer;
+ cd.valueAccessor = this; // ControlDirective should inject CheckboxControlDirective
+ }
+
+ writeValue(value) {
+ this._renderer.setElementProperty(this._elementRef.parentView.render,
+ this._elementRef.boundElementIndex, 'checked', value)
+ }
+}
+
/**
*
* A list of all the form directives used as part of a `@View` annotation.
@@ -270,6 +246,5 @@ export class ControlGroupDirective {
*
* @exportedAs angular2/forms
*/
-export const formDirectives:List = CONST_EXPR([
- ControlGroupDirective, ControlDirective, CheckboxControlValueAccessor, DefaultValueAccessor
-]);
+export const formDirectives: List = CONST_EXPR(
+ [ControlGroupDirective, ControlDirective, CheckboxControlValueAccessor, DefaultValueAccessor]);
diff --git a/modules/angular2/src/forms/form_builder.js b/modules/angular2/src/forms/form_builder.ts
similarity index 81%
rename from modules/angular2/src/forms/form_builder.js
rename to modules/angular2/src/forms/form_builder.ts
index ee58dd6c94..917267c6a9 100644
--- a/modules/angular2/src/forms/form_builder.js
+++ b/modules/angular2/src/forms/form_builder.ts
@@ -51,7 +51,8 @@ import * as modelModule from './model';
* bootstrap(LoginComp)
* ```
*
- * This example creates a {@link ControlGroup} that consists of a `login` {@link Control}, and a nested
+ * 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}:
*
* ```
@@ -68,7 +69,8 @@ import * as modelModule from './model';
* @exportedAs angular2/forms
*/
export class FormBuilder {
- group(controlsConfig, extra = null):modelModule.ControlGroup {
+ group(controlsConfig: StringMap,
+ extra: StringMap = null): modelModule.ControlGroup {
var controls = this._reduceControls(controlsConfig);
var optionals = isPresent(extra) ? StringMapWrapper.get(extra, "optionals") : null;
var validator = isPresent(extra) ? StringMapWrapper.get(extra, "validator") : null;
@@ -80,7 +82,7 @@ export class FormBuilder {
}
}
- control(value, validator:Function = null):modelModule.Control {
+ control(value: Object, validator: Function = null): modelModule.Control {
if (isPresent(validator)) {
return new modelModule.Control(value, validator);
} else {
@@ -88,7 +90,7 @@ export class FormBuilder {
}
}
- array(controlsConfig:List, validator:Function = null):modelModule.ControlArray {
+ array(controlsConfig: List, validator: Function = null): modelModule.ControlArray {
var controls = ListWrapper.map(controlsConfig, (c) => this._createControl(c));
if (isPresent(validator)) {
return new modelModule.ControlArray(controls, validator);
@@ -97,7 +99,7 @@ export class FormBuilder {
}
}
- _reduceControls(controlsConfig) {
+ _reduceControls(controlsConfig: any): StringMap {
var controls = {};
StringMapWrapper.forEach(controlsConfig, (controlConfig, controlName) => {
controls[controlName] = this._createControl(controlConfig);
@@ -105,10 +107,10 @@ export class FormBuilder {
return controls;
}
- _createControl(controlConfig) {
- if (controlConfig instanceof modelModule.Control ||
- controlConfig instanceof modelModule.ControlGroup ||
- controlConfig instanceof modelModule.ControlArray) {
+ _createControl(controlConfig: any): modelModule.AbstractControl {
+ if (controlConfig instanceof modelModule.Control || controlConfig instanceof
+ modelModule.ControlGroup || controlConfig instanceof
+ modelModule.ControlArray) {
return controlConfig;
} else if (ListWrapper.isList(controlConfig)) {
diff --git a/modules/angular2/src/forms/model.js b/modules/angular2/src/forms/model.ts
similarity index 65%
rename from modules/angular2/src/forms/model.js
rename to modules/angular2/src/forms/model.ts
index 027da5e55c..e0ef41ed63 100644
--- a/modules/angular2/src/forms/model.js
+++ b/modules/angular2/src/forms/model.ts
@@ -17,19 +17,7 @@ export const VALID = "VALID";
*/
export const INVALID = "INVALID";
-//interface IControl {
-// get value():any;
-// validator:Function;
-// get status():string;
-// get valid():boolean;
-// get errors():Map;
-// get pristine():boolean;
-// get dirty():boolean;
-// updateValue(value:any){}
-// setParent(parent){}
-//}
-
-export function isControl(c:Object):boolean {
+export function isControl(c: Object): boolean {
return c instanceof AbstractControl;
}
@@ -37,55 +25,39 @@ export function isControl(c:Object):boolean {
/**
* Omitting from external API doc as this is really an abstract internal concept.
*/
-class AbstractControl {
- _value:any;
- _status:string;
- _errors:StringMap;
- _pristine:boolean;
- _parent:any; /* ControlGroup | ControlArray */
- validator:Function;
+export class AbstractControl {
+ _value: any;
+ _status: string;
+ _errors: StringMap;
+ _pristine: boolean;
+ _parent: any; /* ControlGroup | ControlArray */
+ validator: Function;
- _valueChanges:EventEmitter;
+ _valueChanges: EventEmitter;
- constructor(validator:Function) {
+ constructor(validator: Function) {
this.validator = validator;
this._pristine = true;
}
- get value():any {
- return this._value;
- }
+ get value(): any { return this._value; }
- get status():string {
- return this._status;
- }
+ get status(): string { return this._status; }
- get valid():boolean {
- return this._status === VALID;
- }
+ get valid(): boolean { return this._status === VALID; }
- get errors():StringMap {
- return this._errors;
- }
+ get errors(): StringMap { return this._errors; }
- get pristine():boolean {
- return this._pristine;
- }
+ get pristine(): boolean { return this._pristine; }
- get dirty():boolean {
- return ! this.pristine;
- }
+ get dirty(): boolean { return !this.pristine; }
- get valueChanges():Observable {
- return this._valueChanges;
- }
+ get valueChanges(): Observable { return this._valueChanges; }
- setParent(parent){
- this._parent = parent;
- }
+ setParent(parent) { this._parent = parent; }
_updateParent() {
- if (isPresent(this._parent)){
+ if (isPresent(this._parent)) {
this._parent._updateValue();
}
}
@@ -94,19 +66,20 @@ 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
+ * `Control` is one of the three fundamental building blocks used to define forms in Angular, along
+ * with
* {@link ControlGroup} and {@link ControlArray}.
*
* @exportedAs angular2/forms
*/
export class Control extends AbstractControl {
- constructor(value:any, validator:Function = Validators.nullValidator) {
+ constructor(value: any, validator: Function = Validators.nullValidator) {
super(validator);
this._setValueErrorsStatus(value);
this._valueChanges = new EventEmitter();
}
- updateValue(value:any):void {
+ updateValue(value: any): void {
this._setValueErrorsStatus(value);
this._pristine = false;
@@ -115,7 +88,7 @@ export class Control extends AbstractControl {
this._updateParent();
}
- _setValueErrorsStatus(value) {
+ _setValueErrorsStatus(value) {
this._value = value;
this._errors = this.validator(this);
this._status = isPresent(this._errors) ? INVALID : VALID;
@@ -125,21 +98,27 @@ 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
+ * 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
+ * `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.
*
* @exportedAs angular2/forms
*/
export class ControlGroup extends AbstractControl {
- controls:StringMap;
- _optionals:StringMap;
+ controls: StringMap;
+ _optionals: StringMap;
- constructor(controls:StringMap, optionals:StringMap = null, validator:Function = Validators.group) {
+ constructor(controls: StringMap,
+ optionals: StringMap = null,
+ validator: Function = Validators.group) {
super(validator);
this.controls = controls;
this._optionals = isPresent(optionals) ? optionals : {};
@@ -150,25 +129,23 @@ export class ControlGroup extends AbstractControl {
this._setValueErrorsStatus();
}
- include(controlName:string):void {
+ include(controlName: string): void {
StringMapWrapper.set(this._optionals, controlName, true);
this._updateValue();
}
- exclude(controlName:string):void {
+ exclude(controlName: string): void {
StringMapWrapper.set(this._optionals, controlName, false);
this._updateValue();
}
- contains(controlName:string):boolean {
+ contains(controlName: string): boolean {
var c = StringMapWrapper.contains(this.controls, controlName);
return c && this._included(controlName);
}
_setParentForControls() {
- StringMapWrapper.forEach(this.controls, (control, name) => {
- control.setParent(this);
- });
+ StringMapWrapper.forEach(this.controls, (control, name) => { control.setParent(this); });
}
_updateValue() {
@@ -180,7 +157,7 @@ export class ControlGroup extends AbstractControl {
this._updateParent();
}
- _setValueErrorsStatus() {
+ _setValueErrorsStatus() {
this._value = this._reduceValue();
this._errors = this.validator(this);
this._status = isPresent(this._errors) ? INVALID : VALID;
@@ -193,7 +170,7 @@ export class ControlGroup extends AbstractControl {
});
}
- _reduceChildren(initValue:any, fn:Function) {
+ _reduceChildren(initValue: any, fn: Function) {
var res = initValue;
StringMapWrapper.forEach(this.controls, (control, name) => {
if (this._included(name)) {
@@ -203,7 +180,7 @@ export class ControlGroup extends AbstractControl {
return res;
}
- _included(controlName:string):boolean {
+ _included(controlName: string): boolean {
var isOptional = StringMapWrapper.contains(this._optionals, controlName);
return !isOptional || StringMapWrapper.get(this._optionals, controlName);
}
@@ -212,20 +189,24 @@ 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
+ * 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.
*
- * `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
+ * `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.
*
* @exportedAs angular2/forms
*/
export class ControlArray extends AbstractControl {
- controls:List;
+ controls: List;
- constructor(controls:List, validator:Function = Validators.array) {
+ constructor(controls: List, validator: Function = Validators.array) {
super(validator);
this.controls = controls;
@@ -235,30 +216,26 @@ export class ControlArray extends AbstractControl {
this._setValueErrorsStatus();
}
- at(index:number):AbstractControl {
- return this.controls[index];
- }
+ at(index: number): AbstractControl { return this.controls[index]; }
- push(control:AbstractControl):void {
+ push(control: AbstractControl): void {
ListWrapper.push(this.controls, control);
control.setParent(this);
this._updateValue();
}
- insert(index:number, control:AbstractControl):void {
+ insert(index: number, control: AbstractControl): void {
ListWrapper.insert(this.controls, index, control);
control.setParent(this);
this._updateValue();
}
- removeAt(index:number):void {
+ removeAt(index: number): void {
ListWrapper.removeAt(this.controls, index);
this._updateValue();
}
- get length():number {
- return this.controls.length;
- }
+ get length(): number { return this.controls.length; }
_updateValue() {
this._setValueErrorsStatus();
@@ -270,12 +247,10 @@ export class ControlArray extends AbstractControl {
}
_setParentForControls() {
- ListWrapper.forEach(this.controls, (control) => {
- control.setParent(this);
- });
+ ListWrapper.forEach(this.controls, (control) => { control.setParent(this); });
}
- _setValueErrorsStatus() {
+ _setValueErrorsStatus() {
this._value = ListWrapper.map(this.controls, (c) => c.value);
this._errors = this.validator(this);
this._status = isPresent(this._errors) ? INVALID : VALID;
diff --git a/modules/angular2/src/forms/validator_directives.js b/modules/angular2/src/forms/validator_directives.ts
similarity index 58%
rename from modules/angular2/src/forms/validator_directives.js
rename to modules/angular2/src/forms/validator_directives.ts
index f0cef9909a..8c13920bfe 100644
--- a/modules/angular2/src/forms/validator_directives.js
+++ b/modules/angular2/src/forms/validator_directives.ts
@@ -1,13 +1,11 @@
-import {Directive} from 'angular2/src/core/annotations_impl/annotations';
+import {Directive} from 'angular2/src/core/annotations/decorators';
import {Validators} from './validators';
import {ControlDirective} from './directives';
-@Directive({
- selector: '[required]'
-})
+@Directive({selector: '[required]'})
export class RequiredValidatorDirective {
- constructor(c:ControlDirective) {
+ constructor(c: ControlDirective) {
c.validator = Validators.compose([c.validator, Validators.required]);
}
}
diff --git a/modules/angular2/src/forms/validators.js b/modules/angular2/src/forms/validators.ts
similarity index 74%
rename from modules/angular2/src/forms/validators.js
rename to modules/angular2/src/forms/validators.ts
index ac08b56412..0692f12e3d 100644
--- a/modules/angular2/src/forms/validators.js
+++ b/modules/angular2/src/forms/validators.ts
@@ -15,16 +15,14 @@ import * as modelModule from './model';
* @exportedAs angular2/forms
*/
export class Validators {
- static required(c:modelModule.Control) {
+ static required(c: modelModule.Control): StringMap {
return isBlank(c.value) || c.value == "" ? {"required": true} : null;
}
- static nullValidator(c:any) {
- return null;
- }
+ static nullValidator(c: any): StringMap { return null; }
- static compose(validators:List):Function {
- return function (c:modelModule.Control) {
+ static compose(validators: List): Function {
+ return function(c: modelModule.Control) {
var res = ListWrapper.reduce(validators, (res, validator) => {
var errors = validator(c);
return isPresent(errors) ? StringMapWrapper.merge(res, errors) : res;
@@ -33,7 +31,7 @@ export class Validators {
}
}
- static group(c:modelModule.ControlGroup) {
+ static group(c: modelModule.ControlGroup): StringMap {
var res = {};
StringMapWrapper.forEach(c.controls, (control, name) => {
if (c.contains(name) && isPresent(control.errors)) {
@@ -43,7 +41,7 @@ export class Validators {
return StringMapWrapper.isEmpty(res) ? null : res;
}
- static array(c:modelModule.ControlArray) {
+ static array(c: modelModule.ControlArray): StringMap {
var res = {};
ListWrapper.forEach(c.controls, (control) => {
if (isPresent(control.errors)) {
@@ -53,7 +51,7 @@ export class Validators {
return StringMapWrapper.isEmpty(res) ? null : res;
}
- static _mergeErrors(control, res) {
+ static _mergeErrors(control: modelModule.AbstractControl, res: StringMap): void {
StringMapWrapper.forEach(control.errors, (value, error) => {
if (!StringMapWrapper.contains(res, error)) {
res[error] = [];
diff --git a/modules/angular2/src/util/decorators.ts b/modules/angular2/src/util/decorators.ts
index 7a7d5a02a3..b2e63ae296 100644
--- a/modules/angular2/src/util/decorators.ts
+++ b/modules/angular2/src/util/decorators.ts
@@ -1,8 +1,7 @@
import {global} from 'angular2/src/facade/lang';
export function makeDecorator(annotationCls) {
- return function() {
- var args = arguments;
+ return function(... args) {
var Reflect = global.Reflect;
if (!(Reflect && Reflect.getMetadata)) {
throw 'reflect-metadata shim is required when using class decorators';
@@ -19,7 +18,7 @@ export function makeDecorator(annotationCls) {
}
}
-export function makeParamDecorator(annotationCls) {
+export function makeParamDecorator(annotationCls): any {
return function(... args) {
var Reflect = global.Reflect;
if (!(Reflect && Reflect.getMetadata)) {
@@ -28,14 +27,19 @@ export function makeParamDecorator(annotationCls) {
var annotationInstance = Object.create(annotationCls.prototype);
annotationCls.apply(annotationInstance, args);
return function(cls, unusedKey, index) {
- var parameters = Reflect.getMetadata('parameters', cls);
+ var parameters: Array> = Reflect.getMetadata('parameters', cls);
parameters = parameters || [];
+
// there might be gaps if some in between parameters do not have annotations.
// we pad with nulls.
while (parameters.length <= index) {
parameters.push(null);
}
- parameters[index] = annotationInstance;
+
+ parameters[index] = parameters[index] || [];
+ var annotationsForParam: Array = parameters[index];
+ annotationsForParam.push(annotationInstance);
+
Reflect.defineMetadata('parameters', parameters, cls);
return cls;
}
diff --git a/modules/angular2/test/forms/integration_spec.js b/modules/angular2/test/forms/integration_spec.js
index 7418727aeb..fa3df617e8 100644
--- a/modules/angular2/test/forms/integration_spec.js
+++ b/modules/angular2/test/forms/integration_spec.js
@@ -45,6 +45,7 @@ export function main() {
});
}));
+
it("should update the control group values on DOM change",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({