style(lint): re-format modules/@angular
This commit is contained in:
parent
bbed364e7b
commit
f39c9c9e75
|
@ -9,7 +9,7 @@ require('./tools/check-environment')(
|
||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const srcsToFmt = ['tools/**/*.ts'];
|
const srcsToFmt = ['tools/**/*.ts', 'modules/@angular/**/*.ts'];
|
||||||
|
|
||||||
gulp.task('format:enforce', () => {
|
gulp.task('format:enforce', () => {
|
||||||
const format = require('gulp-clang-format');
|
const format = require('gulp-clang-format');
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import {Type} from '@angular/core';
|
import {Type} from '@angular/core';
|
||||||
import {FORM_DIRECTIVES} from './forms-deprecated';
|
|
||||||
import {CORE_DIRECTIVES} from './directives';
|
import {CORE_DIRECTIVES} from './directives';
|
||||||
|
import {FORM_DIRECTIVES} from './forms-deprecated';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of Angular core directives that are likely to be used in each and every Angular
|
* A collection of Angular core directives that are likely to be used in each and every Angular
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
* @description
|
* @description
|
||||||
* Common directives shipped with Angular.
|
* Common directives shipped with Angular.
|
||||||
*/
|
*/
|
||||||
|
export {CORE_DIRECTIVES} from './directives/core_directives';
|
||||||
export {NgClass} from './directives/ng_class';
|
export {NgClass} from './directives/ng_class';
|
||||||
export {NgFor} from './directives/ng_for';
|
export {NgFor} from './directives/ng_for';
|
||||||
export {NgIf} from './directives/ng_if';
|
export {NgIf} from './directives/ng_if';
|
||||||
export {NgTemplateOutlet} from './directives/ng_template_outlet';
|
export {NgLocalization, NgPlural, NgPluralCase} from './directives/ng_plural';
|
||||||
export {NgStyle} from './directives/ng_style';
|
export {NgStyle} from './directives/ng_style';
|
||||||
export {NgSwitch, NgSwitchWhen, NgSwitchDefault} from './directives/ng_switch';
|
export {NgSwitch, NgSwitchDefault, NgSwitchWhen} from './directives/ng_switch';
|
||||||
export {NgPlural, NgPluralCase, NgLocalization} from './directives/ng_plural';
|
export {NgTemplateOutlet} from './directives/ng_template_outlet';
|
||||||
export {CORE_DIRECTIVES} from './directives/core_directives';
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import {Type} from '../facade/lang';
|
import {Type} from '../facade/lang';
|
||||||
|
|
||||||
import {NgClass} from './ng_class';
|
import {NgClass} from './ng_class';
|
||||||
import {NgFor} from './ng_for';
|
import {NgFor} from './ng_for';
|
||||||
import {NgIf} from './ng_if';
|
import {NgIf} from './ng_if';
|
||||||
import {NgTemplateOutlet} from './ng_template_outlet';
|
|
||||||
import {NgStyle} from './ng_style';
|
|
||||||
import {NgSwitch, NgSwitchWhen, NgSwitchDefault} from './ng_switch';
|
|
||||||
import {NgPlural, NgPluralCase} from './ng_plural';
|
import {NgPlural, NgPluralCase} from './ng_plural';
|
||||||
|
import {NgStyle} from './ng_style';
|
||||||
|
import {NgSwitch, NgSwitchDefault, NgSwitchWhen} from './ng_switch';
|
||||||
|
import {NgTemplateOutlet} from './ng_template_outlet';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of Angular core directives that are likely to be used in each and every Angular
|
* A collection of Angular core directives that are likely to be used in each and every Angular
|
||||||
|
@ -59,5 +61,5 @@ export const CORE_DIRECTIVES: Type[] = /*@ts2dart_const*/[
|
||||||
NgSwitchWhen,
|
NgSwitchWhen,
|
||||||
NgSwitchDefault,
|
NgSwitchDefault,
|
||||||
NgPlural,
|
NgPlural,
|
||||||
NgPluralCase
|
NgPluralCase,
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,18 +1,8 @@
|
||||||
import {
|
import {CollectionChangeRecord, Directive, DoCheck, ElementRef, IterableDiffer, IterableDiffers, KeyValueChangeRecord, KeyValueDiffer, KeyValueDiffers, OnDestroy, Renderer} from '@angular/core';
|
||||||
DoCheck,
|
|
||||||
OnDestroy,
|
|
||||||
Directive,
|
|
||||||
ElementRef,
|
|
||||||
IterableDiffers,
|
|
||||||
KeyValueDiffers,
|
|
||||||
Renderer,
|
|
||||||
IterableDiffer,
|
|
||||||
KeyValueDiffer,
|
|
||||||
CollectionChangeRecord,
|
|
||||||
KeyValueChangeRecord
|
|
||||||
} from '@angular/core';
|
|
||||||
import {isPresent, isString, isArray} from '../facade/lang';
|
|
||||||
import {StringMapWrapper, isListLikeIterable} from '../facade/collection';
|
import {StringMapWrapper, isListLikeIterable} from '../facade/collection';
|
||||||
|
import {isArray, isPresent, isString} from '../facade/lang';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `NgClass` directive conditionally adds and removes CSS classes on an HTML element based on
|
* The `NgClass` directive conditionally adds and removes CSS classes on an HTML element based on
|
||||||
|
@ -80,10 +70,11 @@ export class NgClass implements DoCheck, OnDestroy {
|
||||||
private _iterableDiffer: IterableDiffer;
|
private _iterableDiffer: IterableDiffer;
|
||||||
private _keyValueDiffer: KeyValueDiffer;
|
private _keyValueDiffer: KeyValueDiffer;
|
||||||
private _initialClasses: string[] = [];
|
private _initialClasses: string[] = [];
|
||||||
private _rawClass: string[] | Set<string>;
|
private _rawClass: string[]|Set<string>;
|
||||||
|
|
||||||
constructor(private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,
|
constructor(
|
||||||
private _ngEl: ElementRef, private _renderer: Renderer) {}
|
private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,
|
||||||
|
private _ngEl: ElementRef, private _renderer: Renderer) {}
|
||||||
|
|
||||||
set initialClasses(v: string) {
|
set initialClasses(v: string) {
|
||||||
this._applyInitialClasses(true);
|
this._applyInitialClasses(true);
|
||||||
|
@ -92,14 +83,14 @@ export class NgClass implements DoCheck, OnDestroy {
|
||||||
this._applyClasses(this._rawClass, false);
|
this._applyClasses(this._rawClass, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
set rawClass(v: string | string[] | Set<string>| {[key: string]: any}) {
|
set rawClass(v: string|string[]|Set<string>|{[key: string]: any}) {
|
||||||
this._cleanupClasses(this._rawClass);
|
this._cleanupClasses(this._rawClass);
|
||||||
|
|
||||||
if (isString(v)) {
|
if (isString(v)) {
|
||||||
v = (<string>v).split(' ');
|
v = (<string>v).split(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._rawClass = <string[] | Set<string>>v;
|
this._rawClass = <string[]|Set<string>>v;
|
||||||
this._iterableDiffer = null;
|
this._iterableDiffer = null;
|
||||||
this._keyValueDiffer = null;
|
this._keyValueDiffer = null;
|
||||||
if (isPresent(v)) {
|
if (isPresent(v)) {
|
||||||
|
@ -128,7 +119,7 @@ export class NgClass implements DoCheck, OnDestroy {
|
||||||
|
|
||||||
ngOnDestroy(): void { this._cleanupClasses(this._rawClass); }
|
ngOnDestroy(): void { this._cleanupClasses(this._rawClass); }
|
||||||
|
|
||||||
private _cleanupClasses(rawClassVal: string[] | Set<string>| {[key: string]: any}): void {
|
private _cleanupClasses(rawClassVal: string[]|Set<string>|{[key: string]: any}): void {
|
||||||
this._applyClasses(rawClassVal, true);
|
this._applyClasses(rawClassVal, true);
|
||||||
this._applyInitialClasses(false);
|
this._applyInitialClasses(false);
|
||||||
}
|
}
|
||||||
|
@ -156,18 +147,18 @@ export class NgClass implements DoCheck, OnDestroy {
|
||||||
this._initialClasses.forEach(className => this._toggleClass(className, !isCleanup));
|
this._initialClasses.forEach(className => this._toggleClass(className, !isCleanup));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _applyClasses(rawClassVal: string[] | Set<string>| {[key: string]: any},
|
private _applyClasses(
|
||||||
isCleanup: boolean) {
|
rawClassVal: string[]|Set<string>|{[key: string]: any}, isCleanup: boolean) {
|
||||||
if (isPresent(rawClassVal)) {
|
if (isPresent(rawClassVal)) {
|
||||||
if (isArray(rawClassVal)) {
|
if (isArray(rawClassVal)) {
|
||||||
(<string[]>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
|
(<string[]>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
|
||||||
} else if (rawClassVal instanceof Set) {
|
} else if (rawClassVal instanceof Set) {
|
||||||
(<Set<string>>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
|
(<Set<string>>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
|
||||||
} else {
|
} else {
|
||||||
StringMapWrapper.forEach(<{[k: string]: any}>rawClassVal,
|
StringMapWrapper.forEach(
|
||||||
(expVal: any, className: string) => {
|
<{[k: string]: any}>rawClassVal, (expVal: any, className: string) => {
|
||||||
if (isPresent(expVal)) this._toggleClass(className, !isCleanup);
|
if (isPresent(expVal)) this._toggleClass(className, !isCleanup);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
import {
|
import {ChangeDetectorRef, CollectionChangeRecord, DefaultIterableDiffer, Directive, DoCheck, EmbeddedViewRef, IterableDiffer, IterableDiffers, TemplateRef, TrackByFn, ViewContainerRef} from '@angular/core';
|
||||||
DoCheck,
|
|
||||||
Directive,
|
|
||||||
ChangeDetectorRef,
|
|
||||||
IterableDiffer,
|
|
||||||
IterableDiffers,
|
|
||||||
ViewContainerRef,
|
|
||||||
TemplateRef,
|
|
||||||
EmbeddedViewRef,
|
|
||||||
TrackByFn,
|
|
||||||
DefaultIterableDiffer,
|
|
||||||
CollectionChangeRecord
|
|
||||||
} from '@angular/core';
|
|
||||||
import {isPresent, isBlank, getTypeNameForDebugging} from '../facade/lang';
|
|
||||||
import {BaseException} from '../facade/exceptions';
|
import {BaseException} from '../facade/exceptions';
|
||||||
|
import {getTypeNameForDebugging, isBlank, isPresent} from '../facade/lang';
|
||||||
|
|
||||||
export class NgForRow {
|
export class NgForRow {
|
||||||
constructor(public $implicit: any, public index: number, public count: number) {}
|
constructor(public $implicit: any, public index: number, public count: number) {}
|
||||||
|
@ -87,8 +76,9 @@ export class NgFor implements DoCheck {
|
||||||
_ngForTrackBy: TrackByFn;
|
_ngForTrackBy: TrackByFn;
|
||||||
private _differ: IterableDiffer;
|
private _differ: IterableDiffer;
|
||||||
|
|
||||||
constructor(private _viewContainer: ViewContainerRef, private _templateRef: TemplateRef<NgForRow>,
|
constructor(
|
||||||
private _iterableDiffers: IterableDiffers, private _cdr: ChangeDetectorRef) {}
|
private _viewContainer: ViewContainerRef, private _templateRef: TemplateRef<NgForRow>,
|
||||||
|
private _iterableDiffers: IterableDiffers, private _cdr: ChangeDetectorRef) {}
|
||||||
|
|
||||||
set ngForOf(value: any) {
|
set ngForOf(value: any) {
|
||||||
this._ngForOf = value;
|
this._ngForOf = value;
|
||||||
|
@ -121,16 +111,19 @@ export class NgFor implements DoCheck {
|
||||||
// TODO(rado): check if change detection can produce a change record that is
|
// TODO(rado): check if change detection can produce a change record that is
|
||||||
// easier to consume than current.
|
// easier to consume than current.
|
||||||
var recordViewTuples: RecordViewTuple[] = [];
|
var recordViewTuples: RecordViewTuple[] = [];
|
||||||
changes.forEachRemovedItem((removedRecord: CollectionChangeRecord) =>
|
changes.forEachRemovedItem(
|
||||||
recordViewTuples.push(new RecordViewTuple(removedRecord, null)));
|
(removedRecord: CollectionChangeRecord) =>
|
||||||
|
recordViewTuples.push(new RecordViewTuple(removedRecord, null)));
|
||||||
|
|
||||||
changes.forEachMovedItem((movedRecord: CollectionChangeRecord) =>
|
changes.forEachMovedItem(
|
||||||
recordViewTuples.push(new RecordViewTuple(movedRecord, null)));
|
(movedRecord: CollectionChangeRecord) =>
|
||||||
|
recordViewTuples.push(new RecordViewTuple(movedRecord, null)));
|
||||||
|
|
||||||
var insertTuples = this._bulkRemove(recordViewTuples);
|
var insertTuples = this._bulkRemove(recordViewTuples);
|
||||||
|
|
||||||
changes.forEachAddedItem((addedRecord: CollectionChangeRecord) =>
|
changes.forEachAddedItem(
|
||||||
insertTuples.push(new RecordViewTuple(addedRecord, null)));
|
(addedRecord: CollectionChangeRecord) =>
|
||||||
|
insertTuples.push(new RecordViewTuple(addedRecord, null)));
|
||||||
|
|
||||||
this._bulkInsert(insertTuples);
|
this._bulkInsert(insertTuples);
|
||||||
|
|
||||||
|
@ -155,8 +148,9 @@ export class NgFor implements DoCheck {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _bulkRemove(tuples: RecordViewTuple[]): RecordViewTuple[] {
|
private _bulkRemove(tuples: RecordViewTuple[]): RecordViewTuple[] {
|
||||||
tuples.sort((a: RecordViewTuple, b: RecordViewTuple) =>
|
tuples.sort(
|
||||||
a.record.previousIndex - b.record.previousIndex);
|
(a: RecordViewTuple, b: RecordViewTuple) =>
|
||||||
|
a.record.previousIndex - b.record.previousIndex);
|
||||||
var movedTuples: RecordViewTuple[] = [];
|
var movedTuples: RecordViewTuple[] = [];
|
||||||
for (var i = tuples.length - 1; i >= 0; i--) {
|
for (var i = tuples.length - 1; i >= 0; i--) {
|
||||||
var tuple = tuples[i];
|
var tuple = tuples[i];
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import {Directive, ViewContainerRef, TemplateRef} from '@angular/core';
|
import {Directive, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||||
|
|
||||||
import {isBlank} from '../facade/lang';
|
import {isBlank} from '../facade/lang';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes or recreates a portion of the DOM tree based on an {expression}.
|
* Removes or recreates a portion of the DOM tree based on an {expression}.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,15 +1,7 @@
|
||||||
import {
|
import {AfterContentInit, Attribute, ContentChildren, Directive, Input, QueryList, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||||
Directive,
|
|
||||||
ViewContainerRef,
|
|
||||||
TemplateRef,
|
|
||||||
ContentChildren,
|
|
||||||
QueryList,
|
|
||||||
Attribute,
|
|
||||||
AfterContentInit,
|
|
||||||
Input
|
|
||||||
} from '@angular/core';
|
|
||||||
import {isPresent, NumberWrapper} from '../facade/lang';
|
|
||||||
import {Map} from '../facade/collection';
|
import {Map} from '../facade/collection';
|
||||||
|
import {NumberWrapper, isPresent} from '../facade/lang';
|
||||||
|
|
||||||
import {SwitchView} from './ng_switch';
|
import {SwitchView} from './ng_switch';
|
||||||
|
|
||||||
|
@ -81,8 +73,9 @@ export abstract class NgLocalization { abstract getPluralCategory(value: any): s
|
||||||
export class NgPluralCase {
|
export class NgPluralCase {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_view: SwitchView;
|
_view: SwitchView;
|
||||||
constructor(@Attribute('ngPluralCase') public value: string, template: TemplateRef<Object>,
|
constructor(
|
||||||
viewContainer: ViewContainerRef) {
|
@Attribute('ngPluralCase') public value: string, template: TemplateRef<Object>,
|
||||||
|
viewContainer: ViewContainerRef) {
|
||||||
this._view = new SwitchView(viewContainer, template);
|
this._view = new SwitchView(viewContainer, template);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +136,7 @@ export class NgPlural implements AfterContentInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_isValueView(pluralCase: NgPluralCase): boolean { return pluralCase.value[0] === "="; }
|
_isValueView(pluralCase: NgPluralCase): boolean { return pluralCase.value[0] === '='; }
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_formatValue(pluralCase: NgPluralCase): any {
|
_formatValue(pluralCase: NgPluralCase): any {
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
import {
|
import {Directive, DoCheck, ElementRef, KeyValueChangeRecord, KeyValueDiffer, KeyValueDiffers, Renderer} from '@angular/core';
|
||||||
DoCheck,
|
|
||||||
KeyValueChangeRecord,
|
import {isBlank, isPresent} from '../facade/lang';
|
||||||
KeyValueDiffer,
|
|
||||||
KeyValueDiffers,
|
|
||||||
ElementRef,
|
|
||||||
Directive,
|
|
||||||
Renderer
|
|
||||||
} from '@angular/core';
|
|
||||||
import {isPresent, isBlank} from '../facade/lang';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `NgStyle` directive changes styles based on a result of expression evaluation.
|
* The `NgStyle` directive changes styles based on a result of expression evaluation.
|
||||||
|
@ -69,8 +63,8 @@ export class NgStyle implements DoCheck {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_differ: KeyValueDiffer;
|
_differ: KeyValueDiffer;
|
||||||
|
|
||||||
constructor(private _differs: KeyValueDiffers, private _ngEl: ElementRef,
|
constructor(
|
||||||
private _renderer: Renderer) {}
|
private _differs: KeyValueDiffers, private _ngEl: ElementRef, private _renderer: Renderer) {}
|
||||||
|
|
||||||
set rawStyle(v: {[key: string]: string}) {
|
set rawStyle(v: {[key: string]: string}) {
|
||||||
this._rawStyle = v;
|
this._rawStyle = v;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import {Directive, Host, ViewContainerRef, TemplateRef} from '@angular/core';
|
import {Directive, Host, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||||
import {isPresent, isBlank, normalizeBlank} from '../facade/lang';
|
|
||||||
import {ListWrapper, Map} from '../facade/collection';
|
import {ListWrapper, Map} from '../facade/collection';
|
||||||
|
import {isBlank, isPresent, normalizeBlank} from '../facade/lang';
|
||||||
|
|
||||||
const _WHEN_DEFAULT = /*@ts2dart_const*/ new Object();
|
const _WHEN_DEFAULT = /*@ts2dart_const*/ new Object();
|
||||||
|
|
||||||
export class SwitchView {
|
export class SwitchView {
|
||||||
constructor(private _viewContainerRef: ViewContainerRef,
|
constructor(
|
||||||
private _templateRef: TemplateRef<Object>) {}
|
private _viewContainerRef: ViewContainerRef, private _templateRef: TemplateRef<Object>) {}
|
||||||
|
|
||||||
create(): void { this._viewContainerRef.createEmbeddedView(this._templateRef); }
|
create(): void { this._viewContainerRef.createEmbeddedView(this._templateRef); }
|
||||||
|
|
||||||
|
@ -180,8 +181,9 @@ export class NgSwitchWhen {
|
||||||
_view: SwitchView;
|
_view: SwitchView;
|
||||||
private _switch: NgSwitch;
|
private _switch: NgSwitch;
|
||||||
|
|
||||||
constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef<Object>,
|
constructor(
|
||||||
@Host() ngSwitch: NgSwitch) {
|
viewContainer: ViewContainerRef, templateRef: TemplateRef<Object>,
|
||||||
|
@Host() ngSwitch: NgSwitch) {
|
||||||
this._switch = ngSwitch;
|
this._switch = ngSwitch;
|
||||||
this._view = new SwitchView(viewContainer, templateRef);
|
this._view = new SwitchView(viewContainer, templateRef);
|
||||||
}
|
}
|
||||||
|
@ -202,8 +204,9 @@ export class NgSwitchWhen {
|
||||||
*/
|
*/
|
||||||
@Directive({selector: '[ngSwitchDefault]'})
|
@Directive({selector: '[ngSwitchDefault]'})
|
||||||
export class NgSwitchDefault {
|
export class NgSwitchDefault {
|
||||||
constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef<Object>,
|
constructor(
|
||||||
@Host() sswitch: NgSwitch) {
|
viewContainer: ViewContainerRef, templateRef: TemplateRef<Object>,
|
||||||
|
@Host() sswitch: NgSwitch) {
|
||||||
sswitch._registerView(_WHEN_DEFAULT, new SwitchView(viewContainer, templateRef));
|
sswitch._registerView(_WHEN_DEFAULT, new SwitchView(viewContainer, templateRef));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import {Directive, Input, ViewContainerRef, ViewRef, TemplateRef} from '@angular/core';
|
import {Directive, Input, TemplateRef, ViewContainerRef, ViewRef} from '@angular/core';
|
||||||
|
|
||||||
import {isPresent} from '../facade/lang';
|
import {isPresent} from '../facade/lang';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and inserts an embedded view based on a prepared `TemplateRef`.
|
* Creates and inserts an embedded view based on a prepared `TemplateRef`.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,39 +10,32 @@
|
||||||
* Forms providers are not included in default providers; you must import these providers
|
* Forms providers are not included in default providers; you must import these providers
|
||||||
* explicitly.
|
* explicitly.
|
||||||
*/
|
*/
|
||||||
export {AbstractControl, Control, ControlGroup, ControlArray} from './forms-deprecated/model';
|
import {Type} from '@angular/core';
|
||||||
|
|
||||||
|
import {RadioControlRegistry} from './forms-deprecated/directives/radio_control_value_accessor';
|
||||||
|
import {FormBuilder} from './forms-deprecated/form_builder';
|
||||||
|
|
||||||
|
export {FORM_DIRECTIVES, RadioButtonState} from './forms-deprecated/directives';
|
||||||
export {AbstractControlDirective} from './forms-deprecated/directives/abstract_control_directive';
|
export {AbstractControlDirective} from './forms-deprecated/directives/abstract_control_directive';
|
||||||
export {Form} from './forms-deprecated/directives/form_interface';
|
export {CheckboxControlValueAccessor} from './forms-deprecated/directives/checkbox_value_accessor';
|
||||||
export {ControlContainer} from './forms-deprecated/directives/control_container';
|
export {ControlContainer} from './forms-deprecated/directives/control_container';
|
||||||
export {NgControlName} from './forms-deprecated/directives/ng_control_name';
|
|
||||||
export {NgFormControl} from './forms-deprecated/directives/ng_form_control';
|
|
||||||
export {NgModel} from './forms-deprecated/directives/ng_model';
|
|
||||||
export {NgControl} from './forms-deprecated/directives/ng_control';
|
|
||||||
export {NgControlGroup} from './forms-deprecated/directives/ng_control_group';
|
|
||||||
export {NgFormModel} from './forms-deprecated/directives/ng_form_model';
|
|
||||||
export {NgForm} from './forms-deprecated/directives/ng_form';
|
|
||||||
export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './forms-deprecated/directives/control_value_accessor';
|
export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './forms-deprecated/directives/control_value_accessor';
|
||||||
export {DefaultValueAccessor} from './forms-deprecated/directives/default_value_accessor';
|
export {DefaultValueAccessor} from './forms-deprecated/directives/default_value_accessor';
|
||||||
|
export {Form} from './forms-deprecated/directives/form_interface';
|
||||||
|
export {NgControl} from './forms-deprecated/directives/ng_control';
|
||||||
|
export {NgControlGroup} from './forms-deprecated/directives/ng_control_group';
|
||||||
|
export {NgControlName} from './forms-deprecated/directives/ng_control_name';
|
||||||
export {NgControlStatus} from './forms-deprecated/directives/ng_control_status';
|
export {NgControlStatus} from './forms-deprecated/directives/ng_control_status';
|
||||||
export {CheckboxControlValueAccessor} from './forms-deprecated/directives/checkbox_value_accessor';
|
export {NgForm} from './forms-deprecated/directives/ng_form';
|
||||||
export {
|
export {NgFormControl} from './forms-deprecated/directives/ng_form_control';
|
||||||
NgSelectOption,
|
export {NgFormModel} from './forms-deprecated/directives/ng_form_model';
|
||||||
SelectControlValueAccessor
|
export {NgModel} from './forms-deprecated/directives/ng_model';
|
||||||
} from './forms-deprecated/directives/select_control_value_accessor';
|
export {NgSelectOption, SelectControlValueAccessor} from './forms-deprecated/directives/select_control_value_accessor';
|
||||||
export {FORM_DIRECTIVES, RadioButtonState} from './forms-deprecated/directives';
|
export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator, Validator} from './forms-deprecated/directives/validators';
|
||||||
export {NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validators} from './forms-deprecated/validators';
|
|
||||||
export {
|
|
||||||
RequiredValidator,
|
|
||||||
MinLengthValidator,
|
|
||||||
MaxLengthValidator,
|
|
||||||
PatternValidator,
|
|
||||||
Validator
|
|
||||||
} from './forms-deprecated/directives/validators';
|
|
||||||
export {FormBuilder} from './forms-deprecated/form_builder';
|
export {FormBuilder} from './forms-deprecated/form_builder';
|
||||||
import {FormBuilder} from './forms-deprecated/form_builder';
|
export {AbstractControl, Control, ControlArray, ControlGroup} from './forms-deprecated/model';
|
||||||
import {RadioControlRegistry} from './forms-deprecated/directives/radio_control_value_accessor';
|
export {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from './forms-deprecated/validators';
|
||||||
import {Type} from '@angular/core';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shorthand set of providers used for building Angular forms.
|
* Shorthand set of providers used for building Angular forms.
|
||||||
|
|
|
@ -1,60 +1,37 @@
|
||||||
import {Type} from '@angular/core';
|
import {Type} from '@angular/core';
|
||||||
import {NgControlName} from './directives/ng_control_name';
|
|
||||||
import {NgFormControl} from './directives/ng_form_control';
|
|
||||||
import {NgModel} from './directives/ng_model';
|
|
||||||
import {NgControlGroup} from './directives/ng_control_group';
|
|
||||||
import {NgFormModel} from './directives/ng_form_model';
|
|
||||||
import {NgForm} from './directives/ng_form';
|
|
||||||
import {DefaultValueAccessor} from './directives/default_value_accessor';
|
|
||||||
import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||||
|
import {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||||
|
import {NgControlGroup} from './directives/ng_control_group';
|
||||||
|
import {NgControlName} from './directives/ng_control_name';
|
||||||
|
import {NgControlStatus} from './directives/ng_control_status';
|
||||||
|
import {NgForm} from './directives/ng_form';
|
||||||
|
import {NgFormControl} from './directives/ng_form_control';
|
||||||
|
import {NgFormModel} from './directives/ng_form_model';
|
||||||
|
import {NgModel} from './directives/ng_model';
|
||||||
import {NumberValueAccessor} from './directives/number_value_accessor';
|
import {NumberValueAccessor} from './directives/number_value_accessor';
|
||||||
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||||
import {NgControlStatus} from './directives/ng_control_status';
|
import {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
||||||
import {
|
import {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
||||||
SelectControlValueAccessor,
|
import {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators';
|
||||||
NgSelectOption
|
|
||||||
} from './directives/select_control_value_accessor';
|
|
||||||
import {
|
|
||||||
SelectMultipleControlValueAccessor,
|
|
||||||
NgSelectMultipleOption
|
|
||||||
} from './directives/select_multiple_control_value_accessor';
|
|
||||||
import {
|
|
||||||
RequiredValidator,
|
|
||||||
MinLengthValidator,
|
|
||||||
MaxLengthValidator,
|
|
||||||
PatternValidator
|
|
||||||
} from './directives/validators';
|
|
||||||
|
|
||||||
export {NgControlName} from './directives/ng_control_name';
|
|
||||||
export {NgFormControl} from './directives/ng_form_control';
|
|
||||||
export {NgModel} from './directives/ng_model';
|
|
||||||
export {NgControlGroup} from './directives/ng_control_group';
|
|
||||||
export {NgFormModel} from './directives/ng_form_model';
|
|
||||||
export {NgForm} from './directives/ng_form';
|
|
||||||
export {DefaultValueAccessor} from './directives/default_value_accessor';
|
|
||||||
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||||
export {
|
|
||||||
RadioControlValueAccessor,
|
|
||||||
RadioButtonState
|
|
||||||
} from './directives/radio_control_value_accessor';
|
|
||||||
export {NumberValueAccessor} from './directives/number_value_accessor';
|
|
||||||
export {NgControlStatus} from './directives/ng_control_status';
|
|
||||||
export {
|
|
||||||
SelectControlValueAccessor,
|
|
||||||
NgSelectOption
|
|
||||||
} from './directives/select_control_value_accessor';
|
|
||||||
export {
|
|
||||||
SelectMultipleControlValueAccessor,
|
|
||||||
NgSelectMultipleOption
|
|
||||||
} from './directives/select_multiple_control_value_accessor';
|
|
||||||
export {
|
|
||||||
RequiredValidator,
|
|
||||||
MinLengthValidator,
|
|
||||||
MaxLengthValidator,
|
|
||||||
PatternValidator
|
|
||||||
} from './directives/validators';
|
|
||||||
export {NgControl} from './directives/ng_control';
|
|
||||||
export {ControlValueAccessor} from './directives/control_value_accessor';
|
export {ControlValueAccessor} from './directives/control_value_accessor';
|
||||||
|
export {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||||
|
export {NgControl} from './directives/ng_control';
|
||||||
|
export {NgControlGroup} from './directives/ng_control_group';
|
||||||
|
export {NgControlName} from './directives/ng_control_name';
|
||||||
|
export {NgControlStatus} from './directives/ng_control_status';
|
||||||
|
export {NgForm} from './directives/ng_form';
|
||||||
|
export {NgFormControl} from './directives/ng_form_control';
|
||||||
|
export {NgFormModel} from './directives/ng_form_model';
|
||||||
|
export {NgModel} from './directives/ng_model';
|
||||||
|
export {NumberValueAccessor} from './directives/number_value_accessor';
|
||||||
|
export {RadioButtonState, RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||||
|
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';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -95,5 +72,5 @@ export const FORM_DIRECTIVES: Type[] = /*@ts2dart_const*/[
|
||||||
RequiredValidator,
|
RequiredValidator,
|
||||||
MinLengthValidator,
|
MinLengthValidator,
|
||||||
MaxLengthValidator,
|
MaxLengthValidator,
|
||||||
PatternValidator
|
PatternValidator,
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {AbstractControl} from '../model';
|
|
||||||
import {isPresent} from '../../facade/lang';
|
|
||||||
import {unimplemented} from '../../facade/exceptions';
|
import {unimplemented} from '../../facade/exceptions';
|
||||||
|
import {isPresent} from '../../facade/lang';
|
||||||
|
import {AbstractControl} from '../model';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for control directives.
|
* Base class for control directives.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {Directive, Renderer, ElementRef, forwardRef} from '@angular/core';
|
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
export const CHECKBOX_VALUE_ACCESSOR: any = /*@ts2dart_const*/ {
|
export const CHECKBOX_VALUE_ACCESSOR: any = /*@ts2dart_const*/ {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {Form} from './form_interface';
|
|
||||||
import {AbstractControlDirective} from './abstract_control_directive';
|
import {AbstractControlDirective} from './abstract_control_directive';
|
||||||
|
import {Form} from './form_interface';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A directive that contains multiple {@link NgControl}s.
|
* A directive that contains multiple {@link NgControl}s.
|
||||||
|
|
|
@ -34,4 +34,4 @@ export interface ControlValueAccessor {
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const NG_VALUE_ACCESSOR: OpaqueToken =
|
export const NG_VALUE_ACCESSOR: OpaqueToken =
|
||||||
/*@ts2dart_const*/ new OpaqueToken("NgValueAccessor");
|
/*@ts2dart_const*/ new OpaqueToken('NgValueAccessor');
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {isBlank} from '../../facade/lang';
|
import {isBlank} from '../../facade/lang';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
export const DEFAULT_VALUE_ACCESSOR: any = /*@ts2dart_const*/
|
export const DEFAULT_VALUE_ACCESSOR: any = /*@ts2dart_const*/
|
||||||
/* @ts2dart_Provider */ {
|
/* @ts2dart_Provider */ {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import {Control, ControlGroup} from '../model';
|
||||||
|
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {NgControlGroup} from './ng_control_group';
|
import {NgControlGroup} from './ng_control_group';
|
||||||
import {Control, ControlGroup} from '../model';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface that {@link NgFormModel} and {@link NgForm} implement.
|
* An interface that {@link NgFormModel} and {@link NgForm} implement.
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import {unimplemented} from '../../facade/exceptions';
|
import {unimplemented} from '../../facade/exceptions';
|
||||||
|
|
||||||
import {ControlValueAccessor} from './control_value_accessor';
|
|
||||||
import {AbstractControlDirective} from './abstract_control_directive';
|
import {AbstractControlDirective} from './abstract_control_directive';
|
||||||
|
import {ControlValueAccessor} from './control_value_accessor';
|
||||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class that all control directive extend.
|
* A base class that all control directive extend.
|
||||||
* It binds a {@link Control} object to a DOM element.
|
* It binds a {@link Control} object to a DOM element.
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
import {
|
import {Directive, Host, Inject, OnDestroy, OnInit, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
||||||
OnInit,
|
|
||||||
OnDestroy,
|
|
||||||
Directive,
|
|
||||||
Optional,
|
|
||||||
Inject,
|
|
||||||
Host,
|
|
||||||
SkipSelf,
|
|
||||||
forwardRef,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
import {ControlContainer} from './control_container';
|
|
||||||
import {controlPath, composeValidators, composeAsyncValidators} from './shared';
|
|
||||||
import {ControlGroup} from '../model';
|
import {ControlGroup} from '../model';
|
||||||
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
|
import {ControlContainer} from './control_container';
|
||||||
import {Form} from './form_interface';
|
import {Form} from './form_interface';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {composeAsyncValidators, composeValidators, controlPath} from './shared';
|
||||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
|
|
||||||
export const controlGroupProvider: any =
|
export const controlGroupProvider: any =
|
||||||
|
@ -79,9 +71,10 @@ export class NgControlGroup extends ControlContainer implements OnInit,
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_parent: ControlContainer;
|
_parent: ControlContainer;
|
||||||
|
|
||||||
constructor(@Host() @SkipSelf() parent: ControlContainer,
|
constructor(
|
||||||
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
@Host() @SkipSelf() parent: ControlContainer,
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
this._parent = parent;
|
this._parent = parent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,14 @@
|
||||||
import {
|
import {Directive, Host, Inject, OnChanges, OnDestroy, Optional, Self, SimpleChanges, SkipSelf, forwardRef} from '@angular/core';
|
||||||
OnChanges,
|
|
||||||
OnDestroy,
|
|
||||||
SimpleChanges,
|
|
||||||
Directive,
|
|
||||||
forwardRef,
|
|
||||||
Host,
|
|
||||||
SkipSelf,
|
|
||||||
Inject,
|
|
||||||
Optional,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
import {ControlContainer} from './control_container';
|
|
||||||
import {NgControl} from './ng_control';
|
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
|
||||||
import {
|
|
||||||
controlPath,
|
|
||||||
composeValidators,
|
|
||||||
composeAsyncValidators,
|
|
||||||
isPropertyUpdated,
|
|
||||||
selectValueAccessor
|
|
||||||
} from './shared';
|
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
import {ValidatorFn, AsyncValidatorFn} 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 =
|
export const controlNameBinding: any =
|
||||||
|
@ -112,35 +96,37 @@ export class NgControlName extends NgControl implements OnChanges,
|
||||||
/* Array<Validator|Function> */ any[],
|
/* Array<Validator|Function> */ any[],
|
||||||
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
||||||
valueAccessors: ControlValueAccessor[]) {
|
valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (!this._added) {
|
if (!this._added) {
|
||||||
this.formDirective.addControl(this);
|
this.formDirective.addControl(this);
|
||||||
this._added = true;
|
this._added = true;
|
||||||
}
|
}
|
||||||
if (isPropertyUpdated(changes, this.viewModel)) {
|
if (isPropertyUpdated(changes, this.viewModel)) {
|
||||||
this.viewModel = this.model;
|
this.viewModel = this.model;
|
||||||
this.formDirective.updateModel(this, this.model);
|
this.formDirective.updateModel(this, this.model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void { this.formDirective.removeControl(this); }
|
ngOnDestroy(): void { this.formDirective.removeControl(this); }
|
||||||
|
|
||||||
viewToModelUpdate(newValue: any): void {
|
viewToModelUpdate(newValue: any): void {
|
||||||
this.viewModel = newValue;
|
this.viewModel = newValue;
|
||||||
ObservableWrapper.callEmit(this.update, newValue);
|
ObservableWrapper.callEmit(this.update, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
get path(): string[] { return controlPath(this.name, this._parent); }
|
get path(): string[] { return controlPath(this.name, this._parent); }
|
||||||
|
|
||||||
get formDirective(): any { return this._parent.formDirective; }
|
get formDirective(): any { return this._parent.formDirective; }
|
||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
get asyncValidator(): AsyncValidatorFn {
|
||||||
|
return composeAsyncValidators(this._asyncValidators);
|
||||||
|
}
|
||||||
|
|
||||||
get control(): Control { return this.formDirective.getControl(this); }
|
get control(): Control { return this.formDirective.getControl(this); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import {Directive, Self} from '@angular/core';
|
import {Directive, Self} from '@angular/core';
|
||||||
import {NgControl} from './ng_control';
|
|
||||||
import {isPresent} from '../../facade/lang';
|
import {isPresent} from '../../facade/lang';
|
||||||
|
|
||||||
|
import {NgControl} from './ng_control';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive automatically applied to Angular forms that sets CSS classes
|
* Directive automatically applied to Angular forms that sets CSS classes
|
||||||
* based on control status (valid/invalid/dirty/etc).
|
* based on control status (valid/invalid/dirty/etc).
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
import {Directive, forwardRef, Optional, Inject, Self} from '@angular/core';
|
import {Directive, Inject, Optional, Self, forwardRef} from '@angular/core';
|
||||||
import {
|
|
||||||
PromiseWrapper,
|
import {EventEmitter, ObservableWrapper, PromiseWrapper} from '../../facade/async';
|
||||||
ObservableWrapper,
|
|
||||||
EventEmitter
|
|
||||||
} from '../../facade/async';
|
|
||||||
import {ListWrapper} from '../../facade/collection';
|
import {ListWrapper} from '../../facade/collection';
|
||||||
import {isPresent} from '../../facade/lang';
|
import {isPresent} from '../../facade/lang';
|
||||||
import {NgControl} from './ng_control';
|
import {AbstractControl, Control, ControlGroup} from '../model';
|
||||||
import {Form} from './form_interface';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
import {NgControlGroup} from './ng_control_group';
|
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {AbstractControl, ControlGroup, Control} from '../model';
|
import {Form} from './form_interface';
|
||||||
import {setUpControl, setUpControlGroup, composeValidators, composeAsyncValidators} from './shared';
|
import {NgControl} from './ng_control';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {NgControlGroup} from './ng_control_group';
|
||||||
|
import {composeAsyncValidators, composeValidators, setUpControl, setUpControlGroup} from './shared';
|
||||||
|
|
||||||
export const formDirectiveProvider: any =
|
export const formDirectiveProvider: any =
|
||||||
/*@ts2dart_const*/ {provide: ControlContainer, useExisting: forwardRef(() => NgForm)};
|
/*@ts2dart_const*/ {provide: ControlContainer, useExisting: forwardRef(() => NgForm)};
|
||||||
|
@ -93,11 +91,12 @@ export class NgForm extends ControlContainer implements Form {
|
||||||
form: ControlGroup;
|
form: ControlGroup;
|
||||||
ngSubmit = new EventEmitter();
|
ngSubmit = new EventEmitter();
|
||||||
|
|
||||||
constructor(@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
constructor(
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
||||||
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
this.form = new ControlGroup({}, null, composeValidators(validators),
|
this.form = new ControlGroup(
|
||||||
composeAsyncValidators(asyncValidators));
|
{}, null, composeValidators(validators), composeAsyncValidators(asyncValidators));
|
||||||
}
|
}
|
||||||
|
|
||||||
get submitted(): boolean { return this._submitted; }
|
get submitted(): boolean { return this._submitted; }
|
||||||
|
|
|
@ -1,28 +1,14 @@
|
||||||
import {
|
import {Directive, Inject, OnChanges, Optional, Self, SimpleChanges, forwardRef} from '@angular/core';
|
||||||
OnChanges,
|
|
||||||
SimpleChanges,
|
|
||||||
Directive,
|
|
||||||
forwardRef,
|
|
||||||
Inject,
|
|
||||||
Optional,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import {StringMapWrapper} from '../../facade/collection';
|
|
||||||
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
|
import {StringMapWrapper} from '../../facade/collection';
|
||||||
import {NgControl} from './ng_control';
|
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {
|
import {NgControl} from './ng_control';
|
||||||
setUpControl,
|
import {composeAsyncValidators, composeValidators, isPropertyUpdated, selectValueAccessor, setUpControl} from './shared';
|
||||||
composeValidators,
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
composeAsyncValidators,
|
|
||||||
isPropertyUpdated,
|
|
||||||
selectValueAccessor
|
|
||||||
} from './shared';
|
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
|
||||||
|
|
||||||
export const formControlBinding: any =
|
export const formControlBinding: any =
|
||||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||||
|
@ -98,35 +84,37 @@ export class NgFormControl extends NgControl implements OnChanges {
|
||||||
/* Array<Validator|Function> */ any[],
|
/* Array<Validator|Function> */ any[],
|
||||||
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
||||||
valueAccessors: ControlValueAccessor[]) {
|
valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
if (this._isControlChanged(changes)) {
|
if (this._isControlChanged(changes)) {
|
||||||
setUpControl(this.form, this);
|
setUpControl(this.form, this);
|
||||||
this.form.updateValueAndValidity({emitEvent: false});
|
this.form.updateValueAndValidity({emitEvent: false});
|
||||||
}
|
}
|
||||||
if (isPropertyUpdated(changes, this.viewModel)) {
|
if (isPropertyUpdated(changes, this.viewModel)) {
|
||||||
this.form.updateValue(this.model);
|
this.form.updateValue(this.model);
|
||||||
this.viewModel = this.model;
|
this.viewModel = this.model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get path(): string[] { return []; }
|
get path(): string[] { return []; }
|
||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
get asyncValidator(): AsyncValidatorFn {
|
||||||
|
return composeAsyncValidators(this._asyncValidators);
|
||||||
|
}
|
||||||
|
|
||||||
get control(): Control { return this.form; }
|
get control(): Control { return this.form; }
|
||||||
|
|
||||||
viewToModelUpdate(newValue: any): void {
|
viewToModelUpdate(newValue: any): void {
|
||||||
this.viewModel = newValue;
|
this.viewModel = newValue;
|
||||||
ObservableWrapper.callEmit(this.update, newValue);
|
ObservableWrapper.callEmit(this.update, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isControlChanged(changes: {[key: string]: any}): boolean {
|
private _isControlChanged(changes: {[key: string]: any}): boolean {
|
||||||
return StringMapWrapper.contains(changes, "form");
|
return StringMapWrapper.contains(changes, 'form');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,17 @@
|
||||||
import {
|
import {Directive, Inject, OnChanges, Optional, Self, SimpleChanges, forwardRef} from '@angular/core';
|
||||||
SimpleChanges,
|
|
||||||
OnChanges,
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
Directive,
|
|
||||||
forwardRef,
|
|
||||||
Inject,
|
|
||||||
Optional,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
import {isBlank} from '../../facade/lang';
|
|
||||||
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
|
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
|
||||||
import {BaseException} from '../../facade/exceptions';
|
import {BaseException} from '../../facade/exceptions';
|
||||||
import {ObservableWrapper, EventEmitter} from '../../facade/async';
|
import {isBlank} from '../../facade/lang';
|
||||||
import {NgControl} from './ng_control';
|
import {Control, ControlGroup} from '../model';
|
||||||
import {NgControlGroup} from './ng_control_group';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from '../validators';
|
||||||
|
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {Form} from './form_interface';
|
import {Form} from './form_interface';
|
||||||
import {Control, ControlGroup} from '../model';
|
import {NgControl} from './ng_control';
|
||||||
import {setUpControl, setUpControlGroup, composeValidators, composeAsyncValidators} from './shared';
|
import {NgControlGroup} from './ng_control_group';
|
||||||
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {composeAsyncValidators, composeValidators, setUpControl, setUpControlGroup} from './shared';
|
||||||
|
|
||||||
export const formDirectiveProvider: any =
|
export const formDirectiveProvider: any =
|
||||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||||
|
@ -115,14 +109,15 @@ export class NgFormModel extends ControlContainer implements Form,
|
||||||
directives: NgControl[] = [];
|
directives: NgControl[] = [];
|
||||||
ngSubmit = new EventEmitter();
|
ngSubmit = new EventEmitter();
|
||||||
|
|
||||||
constructor(@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
constructor(
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
this._checkFormPresent();
|
this._checkFormPresent();
|
||||||
if (StringMapWrapper.contains(changes, "form")) {
|
if (StringMapWrapper.contains(changes, 'form')) {
|
||||||
var sync = composeValidators(this._validators);
|
var sync = composeValidators(this._validators);
|
||||||
this.form.validator = Validators.compose([this.form.validator, sync]);
|
this.form.validator = Validators.compose([this.form.validator, sync]);
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
import {
|
import {Directive, Inject, OnChanges, Optional, Self, SimpleChanges, forwardRef} from '@angular/core';
|
||||||
OnChanges,
|
|
||||||
SimpleChanges,
|
|
||||||
Directive,
|
|
||||||
forwardRef,
|
|
||||||
Inject,
|
|
||||||
Optional,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
|
import {Control} from '../model';
|
||||||
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {Control} from '../model';
|
import {composeAsyncValidators, composeValidators, isPropertyUpdated, selectValueAccessor, setUpControl} from './shared';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
import {
|
|
||||||
setUpControl,
|
|
||||||
isPropertyUpdated,
|
|
||||||
selectValueAccessor,
|
|
||||||
composeValidators,
|
|
||||||
composeAsyncValidators
|
|
||||||
} from './shared';
|
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
|
||||||
|
|
||||||
export const formControlBinding: any =
|
export const formControlBinding: any =
|
||||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||||
|
@ -70,33 +58,35 @@ export class NgModel extends NgControl implements OnChanges {
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[],
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[],
|
||||||
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
||||||
valueAccessors: ControlValueAccessor[]) {
|
valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (!this._added) {
|
if (!this._added) {
|
||||||
setUpControl(this._control, this);
|
setUpControl(this._control, this);
|
||||||
this._control.updateValueAndValidity({emitEvent: false});
|
this._control.updateValueAndValidity({emitEvent: false});
|
||||||
this._added = true;
|
this._added = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPropertyUpdated(changes, this.viewModel)) {
|
if (isPropertyUpdated(changes, this.viewModel)) {
|
||||||
this._control.updateValue(this.model);
|
this._control.updateValue(this.model);
|
||||||
this.viewModel = this.model;
|
this.viewModel = this.model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get control(): Control { return this._control; }
|
get control(): Control { return this._control; }
|
||||||
|
|
||||||
get path(): string[] { return []; }
|
get path(): string[] { return []; }
|
||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
get asyncValidator(): AsyncValidatorFn {
|
||||||
|
return composeAsyncValidators(this._asyncValidators);
|
||||||
|
}
|
||||||
|
|
||||||
viewToModelUpdate(newValue: any): void {
|
viewToModelUpdate(newValue: any): void {
|
||||||
this.viewModel = newValue;
|
this.viewModel = newValue;
|
||||||
ObservableWrapper.callEmit(this.update, newValue);
|
ObservableWrapper.callEmit(this.update, newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {AbstractControl} from '../model';
|
import {AbstractControl} from '../model';
|
||||||
import {Validator, ValidatorFn, AsyncValidatorFn} from './validators';
|
|
||||||
|
import {AsyncValidatorFn, Validator, ValidatorFn} from './validators';
|
||||||
|
|
||||||
export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn {
|
export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn {
|
||||||
if ((<Validator>validator).validate !== undefined) {
|
if ((<Validator>validator).validate !== undefined) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {NumberWrapper} from '../../facade/lang';
|
import {NumberWrapper} from '../../facade/lang';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
export const NUMBER_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
export const NUMBER_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
import {
|
import {Directive, ElementRef, Injectable, Injector, Input, OnDestroy, OnInit, Renderer, forwardRef} from '@angular/core';
|
||||||
Directive,
|
|
||||||
ElementRef,
|
|
||||||
Renderer,
|
|
||||||
forwardRef,
|
|
||||||
Input,
|
|
||||||
OnInit,
|
|
||||||
OnDestroy,
|
|
||||||
Injector,
|
|
||||||
Injectable
|
|
||||||
} from '@angular/core';
|
|
||||||
import {isPresent} from '../../facade/lang';
|
|
||||||
import {ListWrapper} from '../../facade/collection';
|
import {ListWrapper} from '../../facade/collection';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
import {isPresent} from '../../facade/lang';
|
||||||
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
|
|
||||||
export const RADIO_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
export const RADIO_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
||||||
|
@ -49,10 +41,10 @@ export class RadioControlRegistry {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isSameGroup(controlPair:[NgControl, RadioControlValueAccessor],
|
private _isSameGroup(
|
||||||
accessor: RadioControlValueAccessor) {
|
controlPair: [NgControl, RadioControlValueAccessor], accessor: RadioControlValueAccessor) {
|
||||||
return controlPair[0].control.root === accessor._control.control.root &&
|
return controlPair[0].control.root === accessor._control.control.root &&
|
||||||
controlPair[1].name === accessor.name;
|
controlPair[1].name === accessor.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +94,9 @@ export class RadioControlValueAccessor implements ControlValueAccessor,
|
||||||
onChange = () => {};
|
onChange = () => {};
|
||||||
onTouched = () => {};
|
onTouched = () => {};
|
||||||
|
|
||||||
constructor(private _renderer: Renderer, private _elementRef: ElementRef,
|
constructor(
|
||||||
private _registry: RadioControlRegistry, private _injector: Injector) {}
|
private _renderer: Renderer, private _elementRef: ElementRef,
|
||||||
|
private _registry: RadioControlRegistry, private _injector: Injector) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this._control = this._injector.get(NgControl);
|
this._control = this._injector.get(NgControl);
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
import {
|
import {Directive, ElementRef, Host, Input, OnDestroy, Optional, Renderer, forwardRef} from '@angular/core';
|
||||||
Directive,
|
|
||||||
Renderer,
|
|
||||||
forwardRef,
|
|
||||||
ElementRef,
|
|
||||||
Input,
|
|
||||||
Host,
|
|
||||||
OnDestroy,
|
|
||||||
Optional
|
|
||||||
} from '@angular/core';
|
|
||||||
import {
|
|
||||||
StringWrapper,
|
|
||||||
isPrimitive,
|
|
||||||
isPresent,
|
|
||||||
isBlank,
|
|
||||||
looseIdentical
|
|
||||||
} from '../../facade/lang';
|
|
||||||
import {MapWrapper} from '../../facade/collection';
|
|
||||||
|
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
import {MapWrapper} from '../../facade/collection';
|
||||||
|
import {StringWrapper, isBlank, isPresent, isPrimitive, looseIdentical} from '../../facade/lang';
|
||||||
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
export const SELECT_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
export const SELECT_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
@ -27,12 +13,12 @@ export const SELECT_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider
|
||||||
|
|
||||||
function _buildValueString(id: string, value: any): string {
|
function _buildValueString(id: string, value: any): string {
|
||||||
if (isBlank(id)) return `${value}`;
|
if (isBlank(id)) return `${value}`;
|
||||||
if (!isPrimitive(value)) value = "Object";
|
if (!isPrimitive(value)) value = 'Object';
|
||||||
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _extractId(valueString: string): string {
|
function _extractId(valueString: string): string {
|
||||||
return valueString.split(":")[0];
|
return valueString.split(':')[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,8 +98,9 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
|
||||||
export class NgSelectOption implements OnDestroy {
|
export class NgSelectOption implements OnDestroy {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
constructor(private _element: ElementRef, private _renderer: Renderer,
|
constructor(
|
||||||
@Optional() @Host() private _select: SelectControlValueAccessor) {
|
private _element: ElementRef, private _renderer: Renderer,
|
||||||
|
@Optional() @Host() private _select: SelectControlValueAccessor) {
|
||||||
if (isPresent(this._select)) this.id = this._select._registerOption();
|
if (isPresent(this._select)) this.id = this._select._registerOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
import {
|
import {Directive, ElementRef, Host, Input, OnDestroy, Optional, Renderer, forwardRef} from '@angular/core';
|
||||||
Input,
|
|
||||||
Directive,
|
|
||||||
ElementRef,
|
|
||||||
Renderer,
|
|
||||||
Optional,
|
|
||||||
Host,
|
|
||||||
OnDestroy,
|
|
||||||
forwardRef
|
|
||||||
} from "@angular/core";
|
|
||||||
import {
|
|
||||||
isBlank,
|
|
||||||
isPrimitive,
|
|
||||||
StringWrapper,
|
|
||||||
isPresent,
|
|
||||||
looseIdentical,
|
|
||||||
isString
|
|
||||||
} from '../../facade/lang';
|
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
|
||||||
import {MapWrapper} from '../../facade/collection';
|
import {MapWrapper} from '../../facade/collection';
|
||||||
|
import {StringWrapper, isBlank, isPresent, isPrimitive, isString, looseIdentical} from '../../facade/lang';
|
||||||
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
const SELECT_MULTIPLE_VALUE_ACCESSOR = {
|
const SELECT_MULTIPLE_VALUE_ACCESSOR = {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
@ -28,12 +14,12 @@ const SELECT_MULTIPLE_VALUE_ACCESSOR = {
|
||||||
function _buildValueString(id: string, value: any): string {
|
function _buildValueString(id: string, value: any): string {
|
||||||
if (isBlank(id)) return `${value}`;
|
if (isBlank(id)) return `${value}`;
|
||||||
if (isString(value)) value = `'${value}'`;
|
if (isString(value)) value = `'${value}'`;
|
||||||
if (!isPrimitive(value)) value = "Object";
|
if (!isPrimitive(value)) value = 'Object';
|
||||||
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _extractId(valueString: string): string {
|
function _extractId(valueString: string): string {
|
||||||
return valueString.split(":")[0];
|
return valueString.split(':')[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mock interface for HTML Options */
|
/** Mock interface for HTML Options */
|
||||||
|
@ -74,9 +60,7 @@ export class SelectMultipleControlValueAccessor implements ControlValueAccessor
|
||||||
let values: Array<any> = <Array<any>>value;
|
let values: Array<any> = <Array<any>>value;
|
||||||
// convert values to ids
|
// convert values to ids
|
||||||
let ids = values.map((v) => this._getOptionId(v));
|
let ids = values.map((v) => this._getOptionId(v));
|
||||||
this._optionMap.forEach((opt, o) => {
|
this._optionMap.forEach((opt, o) => { opt._setSelected(ids.indexOf(o.toString()) > -1); });
|
||||||
opt._setSelected(ids.indexOf(o.toString()) > -1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
registerOnChange(fn: (value: any) => any): void {
|
registerOnChange(fn: (value: any) => any): void {
|
||||||
|
@ -108,7 +92,7 @@ export class SelectMultipleControlValueAccessor implements ControlValueAccessor
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_registerOption(value: NgSelectMultipleOption): string {
|
_registerOption(value: NgSelectMultipleOption): string {
|
||||||
let id:string = (this._idCounter++).toString();
|
let id: string = (this._idCounter++).toString();
|
||||||
this._optionMap.set(id, value);
|
this._optionMap.set(id, value);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -145,8 +129,9 @@ export class NgSelectMultipleOption implements OnDestroy {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_value: any;
|
_value: any;
|
||||||
|
|
||||||
constructor(private _element: ElementRef, private _renderer: Renderer,
|
constructor(
|
||||||
@Optional() @Host() private _select: SelectMultipleControlValueAccessor) {
|
private _element: ElementRef, private _renderer: Renderer,
|
||||||
|
@Optional() @Host() private _select: SelectMultipleControlValueAccessor) {
|
||||||
if (isPresent(this._select)) {
|
if (isPresent(this._select)) {
|
||||||
this.id = this._select._registerOption(this);
|
this.id = this._select._registerOption(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
|
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
|
||||||
import {isBlank, isPresent, looseIdentical, hasConstructor} from '../../facade/lang';
|
|
||||||
import {BaseException} from '../../facade/exceptions';
|
import {BaseException} from '../../facade/exceptions';
|
||||||
|
import {hasConstructor, isBlank, isPresent, looseIdentical} from '../../facade/lang';
|
||||||
import {ControlContainer} from './control_container';
|
|
||||||
import {NgControl} from './ng_control';
|
|
||||||
import {AbstractControlDirective} from './abstract_control_directive';
|
|
||||||
import {NgControlGroup} from './ng_control_group';
|
|
||||||
import {Control, ControlGroup} from '../model';
|
import {Control, ControlGroup} from '../model';
|
||||||
import {Validators} from '../validators';
|
import {Validators} from '../validators';
|
||||||
|
|
||||||
|
import {AbstractControlDirective} from './abstract_control_directive';
|
||||||
|
import {CheckboxControlValueAccessor} from './checkbox_value_accessor';
|
||||||
|
import {ControlContainer} from './control_container';
|
||||||
import {ControlValueAccessor} from './control_value_accessor';
|
import {ControlValueAccessor} from './control_value_accessor';
|
||||||
import {DefaultValueAccessor} from './default_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 {NumberValueAccessor} from './number_value_accessor';
|
||||||
import {CheckboxControlValueAccessor} from './checkbox_value_accessor';
|
|
||||||
import {SelectControlValueAccessor} from './select_control_value_accessor';
|
|
||||||
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
||||||
import {normalizeValidator, normalizeAsyncValidator} from './normalize_validator';
|
import {SelectControlValueAccessor} from './select_control_value_accessor';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
|
|
||||||
|
|
||||||
export function controlPath(name: string, parent: ControlContainer): string[] {
|
export function controlPath(name: string, parent: ControlContainer): string[] {
|
||||||
|
@ -25,8 +25,8 @@ export function controlPath(name: string, parent: ControlContainer): string[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setUpControl(control: Control, dir: NgControl): void {
|
export function setUpControl(control: Control, dir: NgControl): void {
|
||||||
if (isBlank(control)) _throwError(dir, "Cannot find control");
|
if (isBlank(control)) _throwError(dir, 'Cannot find control');
|
||||||
if (isBlank(dir.valueAccessor)) _throwError(dir, "No value accessor for");
|
if (isBlank(dir.valueAccessor)) _throwError(dir, 'No value accessor for');
|
||||||
|
|
||||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||||
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||||
|
@ -47,13 +47,13 @@ export function setUpControl(control: Control, dir: NgControl): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
|
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
|
||||||
if (isBlank(control)) _throwError(dir, "Cannot find control");
|
if (isBlank(control)) _throwError(dir, 'Cannot find control');
|
||||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||||
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _throwError(dir: AbstractControlDirective, message: string): void {
|
function _throwError(dir: AbstractControlDirective, message: string): void {
|
||||||
var path = dir.path.join(" -> ");
|
var path = dir.path.join(' -> ');
|
||||||
throw new BaseException(`${message} '${path}'`);
|
throw new BaseException(`${message} '${path}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,23 +61,23 @@ export function composeValidators(validators: /* Array<Validator|Function> */ an
|
||||||
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
|
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function composeAsyncValidators(
|
export function composeAsyncValidators(validators: /* Array<Validator|Function> */ any[]):
|
||||||
validators: /* Array<Validator|Function> */ any[]): AsyncValidatorFn {
|
AsyncValidatorFn {
|
||||||
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
|
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
||||||
if (!StringMapWrapper.contains(changes, "model")) return false;
|
if (!StringMapWrapper.contains(changes, 'model')) return false;
|
||||||
var change = changes["model"];
|
var change = changes['model'];
|
||||||
|
|
||||||
if (change.isFirstChange()) return true;
|
if (change.isFirstChange()) return true;
|
||||||
return !looseIdentical(viewModel, change.currentValue);
|
return !looseIdentical(viewModel, change.currentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
|
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
|
||||||
export function selectValueAccessor(dir: NgControl,
|
export function selectValueAccessor(
|
||||||
valueAccessors: ControlValueAccessor[]): ControlValueAccessor {
|
dir: NgControl, valueAccessors: ControlValueAccessor[]): ControlValueAccessor {
|
||||||
if (isBlank(valueAccessors)) return null;
|
if (isBlank(valueAccessors)) return null;
|
||||||
|
|
||||||
var defaultAccessor: ControlValueAccessor;
|
var defaultAccessor: ControlValueAccessor;
|
||||||
|
@ -87,17 +87,17 @@ export function selectValueAccessor(dir: NgControl,
|
||||||
if (hasConstructor(v, DefaultValueAccessor)) {
|
if (hasConstructor(v, DefaultValueAccessor)) {
|
||||||
defaultAccessor = v;
|
defaultAccessor = v;
|
||||||
|
|
||||||
} else if (hasConstructor(v, CheckboxControlValueAccessor) ||
|
} else if (
|
||||||
hasConstructor(v, NumberValueAccessor) ||
|
hasConstructor(v, CheckboxControlValueAccessor) || hasConstructor(v, NumberValueAccessor) ||
|
||||||
hasConstructor(v, SelectControlValueAccessor) ||
|
hasConstructor(v, SelectControlValueAccessor) ||
|
||||||
hasConstructor(v, RadioControlValueAccessor)) {
|
hasConstructor(v, RadioControlValueAccessor)) {
|
||||||
if (isPresent(builtinAccessor))
|
if (isPresent(builtinAccessor))
|
||||||
_throwError(dir, "More than one built-in value accessor matches");
|
_throwError(dir, 'More than one built-in value accessor matches');
|
||||||
builtinAccessor = v;
|
builtinAccessor = v;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (isPresent(customAccessor))
|
if (isPresent(customAccessor))
|
||||||
_throwError(dir, "More than one custom value accessor matches");
|
_throwError(dir, 'More than one custom value accessor matches');
|
||||||
customAccessor = v;
|
customAccessor = v;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -106,6 +106,6 @@ export function selectValueAccessor(dir: NgControl,
|
||||||
if (isPresent(builtinAccessor)) return builtinAccessor;
|
if (isPresent(builtinAccessor)) return builtinAccessor;
|
||||||
if (isPresent(defaultAccessor)) return defaultAccessor;
|
if (isPresent(defaultAccessor)) return defaultAccessor;
|
||||||
|
|
||||||
_throwError(dir, "No valid value accessor for");
|
_throwError(dir, 'No valid value accessor for');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import {forwardRef, Attribute, Directive} from '@angular/core';
|
import {Attribute, Directive, forwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {NumberWrapper} from '../../facade/lang';
|
import {NumberWrapper} from '../../facade/lang';
|
||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
|
||||||
import {AbstractControl} from '../model';
|
import {AbstractControl} from '../model';
|
||||||
|
import {NG_VALIDATORS, Validators} from '../validators';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ export const MIN_LENGTH_VALIDATOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*
|
||||||
export class MinLengthValidator implements Validator {
|
export class MinLengthValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute("minlength") minLength: string) {
|
constructor(@Attribute('minlength') minLength: string) {
|
||||||
this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10));
|
this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ export const MAX_LENGTH_VALIDATOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*
|
||||||
export class MaxLengthValidator implements Validator {
|
export class MaxLengthValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute("maxlength") maxLength: string) {
|
constructor(@Attribute('maxlength') maxLength: string) {
|
||||||
this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10));
|
this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +151,7 @@ export const PATTERN_VALIDATOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
||||||
export class PatternValidator implements Validator {
|
export class PatternValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute("pattern") pattern: string) {
|
constructor(@Attribute('pattern') pattern: string) {
|
||||||
this._validator = Validators.pattern(pattern);
|
this._validator = Validators.pattern(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
|
|
||||||
import {StringMapWrapper} from '../facade/collection';
|
import {StringMapWrapper} from '../facade/collection';
|
||||||
import {isPresent, isArray} from '../facade/lang';
|
import {isArray, isPresent} from '../facade/lang';
|
||||||
|
|
||||||
|
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
|
||||||
import * as modelModule from './model';
|
import * as modelModule from './model';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,21 +59,21 @@ export class FormBuilder {
|
||||||
*
|
*
|
||||||
* See the {@link ControlGroup} constructor for more details.
|
* See the {@link ControlGroup} constructor for more details.
|
||||||
*/
|
*/
|
||||||
group(controlsConfig: {[key: string]: any},
|
group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any} = null):
|
||||||
extra: {[key: string]: any} = null): modelModule.ControlGroup {
|
modelModule.ControlGroup {
|
||||||
var controls = this._reduceControls(controlsConfig);
|
var controls = this._reduceControls(controlsConfig);
|
||||||
var optionals = <{[key: string]: boolean}>(
|
var optionals = <{[key: string]: boolean}>(
|
||||||
isPresent(extra) ? StringMapWrapper.get(extra, "optionals") : null);
|
isPresent(extra) ? StringMapWrapper.get(extra, 'optionals') : null);
|
||||||
var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, "validator") : null;
|
var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, 'validator') : null;
|
||||||
var asyncValidator: AsyncValidatorFn =
|
var asyncValidator: AsyncValidatorFn =
|
||||||
isPresent(extra) ? StringMapWrapper.get(extra, "asyncValidator") : null;
|
isPresent(extra) ? StringMapWrapper.get(extra, 'asyncValidator') : null;
|
||||||
return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator);
|
return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`.
|
* Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`.
|
||||||
*/
|
*/
|
||||||
control(value: Object, validator: ValidatorFn = null,
|
control(value: Object, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null):
|
||||||
asyncValidator: AsyncValidatorFn = null): modelModule.Control {
|
modelModule.Control {
|
||||||
return new modelModule.Control(value, validator, asyncValidator);
|
return new modelModule.Control(value, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,15 +81,16 @@ export class FormBuilder {
|
||||||
* Construct an array of {@link Control}s from the given `controlsConfig` array of
|
* Construct an array of {@link Control}s from the given `controlsConfig` array of
|
||||||
* configuration, with the given optional `validator` and `asyncValidator`.
|
* configuration, with the given optional `validator` and `asyncValidator`.
|
||||||
*/
|
*/
|
||||||
array(controlsConfig: any[], validator: ValidatorFn = null,
|
array(
|
||||||
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray {
|
controlsConfig: any[], validator: ValidatorFn = null,
|
||||||
|
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray {
|
||||||
var controls = controlsConfig.map(c => this._createControl(c));
|
var controls = controlsConfig.map(c => this._createControl(c));
|
||||||
return new modelModule.ControlArray(controls, validator, asyncValidator);
|
return new modelModule.ControlArray(controls, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_reduceControls(controlsConfig: {[k: string]:
|
_reduceControls(controlsConfig: {[k: string]: any}):
|
||||||
any}): {[key: string]: modelModule.AbstractControl} {
|
{[key: string]: modelModule.AbstractControl} {
|
||||||
var controls: {[key: string]: modelModule.AbstractControl} = {};
|
var controls: {[key: string]: modelModule.AbstractControl} = {};
|
||||||
StringMapWrapper.forEach(controlsConfig, (controlConfig: any, controlName: string) => {
|
StringMapWrapper.forEach(controlsConfig, (controlConfig: any, controlName: string) => {
|
||||||
controls[controlName] = this._createControl(controlConfig);
|
controls[controlName] = this._createControl(controlConfig);
|
||||||
|
|
|
@ -1,48 +1,49 @@
|
||||||
import {isPresent, isBlank, normalizeBool} from '../facade/lang';
|
import {EventEmitter, Observable, ObservableWrapper} from '../facade/async';
|
||||||
import {Observable, EventEmitter, ObservableWrapper} from '../facade/async';
|
import {ListWrapper, StringMapWrapper} from '../facade/collection';
|
||||||
|
import {isBlank, isPresent, normalizeBool} from '../facade/lang';
|
||||||
import {PromiseWrapper} from '../facade/promise';
|
import {PromiseWrapper} from '../facade/promise';
|
||||||
import {StringMapWrapper, ListWrapper} from '../facade/collection';
|
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that a Control is valid, i.e. that no errors exist in the input value.
|
* Indicates that a Control is valid, i.e. that no errors exist in the input value.
|
||||||
*/
|
*/
|
||||||
export const VALID = "VALID";
|
export const VALID = 'VALID';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that a Control is invalid, i.e. that an error exists in the input value.
|
* Indicates that a Control is invalid, i.e. that an error exists in the input value.
|
||||||
*/
|
*/
|
||||||
export const INVALID = "INVALID";
|
export const INVALID = 'INVALID';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that a Control is pending, i.e. that async validation is occurring and
|
* Indicates that a Control is pending, i.e. that async validation is occurring and
|
||||||
* errors are not yet available for the input value.
|
* errors are not yet available for the input value.
|
||||||
*/
|
*/
|
||||||
export const PENDING = "PENDING";
|
export const PENDING = 'PENDING';
|
||||||
|
|
||||||
export function isControl(control: Object): boolean {
|
export function isControl(control: Object): boolean {
|
||||||
return control instanceof AbstractControl;
|
return control instanceof AbstractControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _find(control: AbstractControl, path: Array<string | number>| string) {
|
function _find(control: AbstractControl, path: Array<string|number>| string) {
|
||||||
if (isBlank(path)) return null;
|
if (isBlank(path)) return null;
|
||||||
|
|
||||||
if (!(path instanceof Array)) {
|
if (!(path instanceof Array)) {
|
||||||
path = (<string>path).split("/");
|
path = (<string>path).split('/');
|
||||||
}
|
}
|
||||||
if (path instanceof Array && ListWrapper.isEmpty(path)) return null;
|
if (path instanceof Array && ListWrapper.isEmpty(path)) return null;
|
||||||
|
|
||||||
return (<Array<string | number>>path)
|
return (<Array<string|number>>path).reduce((v, name) => {
|
||||||
.reduce((v, name) => {
|
if (v instanceof ControlGroup) {
|
||||||
if (v instanceof ControlGroup) {
|
return isPresent(v.controls[name]) ? v.controls[name] : null;
|
||||||
return isPresent(v.controls[name]) ? v.controls[name] : null;
|
} else if (v instanceof ControlArray) {
|
||||||
} else if (v instanceof ControlArray) {
|
var index = <number>name;
|
||||||
var index = <number>name;
|
return isPresent(v.at(index)) ? v.at(index) : null;
|
||||||
return isPresent(v.at(index)) ? v.at(index) : null;
|
} else {
|
||||||
} else {
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
}, control);
|
||||||
}, control);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toObservable(r: any): Observable<any> {
|
function toObservable(r: any): Observable<any> {
|
||||||
|
@ -62,7 +63,7 @@ export abstract class AbstractControl {
|
||||||
private _errors: {[key: string]: any};
|
private _errors: {[key: string]: any};
|
||||||
private _pristine: boolean = true;
|
private _pristine: boolean = true;
|
||||||
private _touched: boolean = false;
|
private _touched: boolean = false;
|
||||||
private _parent: ControlGroup | ControlArray;
|
private _parent: ControlGroup|ControlArray;
|
||||||
private _asyncValidationSubscription: any;
|
private _asyncValidationSubscription: any;
|
||||||
|
|
||||||
constructor(public validator: ValidatorFn, public asyncValidator: AsyncValidatorFn) {}
|
constructor(public validator: ValidatorFn, public asyncValidator: AsyncValidatorFn) {}
|
||||||
|
@ -112,10 +113,10 @@ export abstract class AbstractControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; }
|
setParent(parent: ControlGroup|ControlArray): void { this._parent = parent; }
|
||||||
|
|
||||||
updateValueAndValidity(
|
updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
|
||||||
{onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
|
void {
|
||||||
onlySelf = normalizeBool(onlySelf);
|
onlySelf = normalizeBool(onlySelf);
|
||||||
emitEvent = isPresent(emitEvent) ? emitEvent : true;
|
emitEvent = isPresent(emitEvent) ? emitEvent : true;
|
||||||
|
|
||||||
|
@ -196,7 +197,7 @@ export abstract class AbstractControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
find(path: Array<string | number>| string): AbstractControl { return _find(this, path); }
|
find(path: Array<string|number>|string): AbstractControl { return _find(this, path); }
|
||||||
|
|
||||||
getError(errorCode: string, path: string[] = null): any {
|
getError(errorCode: string, path: string[] = null): any {
|
||||||
var control = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this;
|
var control = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this;
|
||||||
|
@ -273,8 +274,8 @@ export class Control extends AbstractControl {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_onChange: Function;
|
_onChange: Function;
|
||||||
|
|
||||||
constructor(value: any = null, validator: ValidatorFn = null,
|
constructor(
|
||||||
asyncValidator: AsyncValidatorFn = null) {
|
value: any = null, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._value = value;
|
this._value = value;
|
||||||
this.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
this.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
||||||
|
@ -339,9 +340,9 @@ export class Control extends AbstractControl {
|
||||||
export class ControlGroup extends AbstractControl {
|
export class ControlGroup extends AbstractControl {
|
||||||
private _optionals: {[key: string]: boolean};
|
private _optionals: {[key: string]: boolean};
|
||||||
|
|
||||||
constructor(public controls: {[key: string]: AbstractControl},
|
constructor(
|
||||||
optionals: {[key: string]: boolean} = null, validator: ValidatorFn = null,
|
public controls: {[key: string]: AbstractControl}, optionals: {[key: string]: boolean} = null,
|
||||||
asyncValidator: AsyncValidatorFn = null) {
|
validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._optionals = isPresent(optionals) ? optionals : {};
|
this._optionals = isPresent(optionals) ? optionals : {};
|
||||||
this._initObservables();
|
this._initObservables();
|
||||||
|
@ -467,8 +468,9 @@ export class ControlGroup extends AbstractControl {
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export class ControlArray extends AbstractControl {
|
export class ControlArray extends AbstractControl {
|
||||||
constructor(public controls: AbstractControl[], validator: ValidatorFn = null,
|
constructor(
|
||||||
asyncValidator: AsyncValidatorFn = null) {
|
public controls: AbstractControl[], validator: ValidatorFn = null,
|
||||||
|
asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._initObservables();
|
this._initObservables();
|
||||||
this._setParentForControls();
|
this._setParentForControls();
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import {OpaqueToken} from '@angular/core';
|
import {OpaqueToken} from '@angular/core';
|
||||||
import {isBlank, isPresent, isString} from '../facade/lang';
|
|
||||||
import {PromiseWrapper} from '../facade/promise';
|
|
||||||
import {ObservableWrapper} from '../facade/async';
|
import {ObservableWrapper} from '../facade/async';
|
||||||
import {StringMapWrapper} from '../facade/collection';
|
import {StringMapWrapper} from '../facade/collection';
|
||||||
|
import {isBlank, isPresent, isString} from '../facade/lang';
|
||||||
|
import {PromiseWrapper} from '../facade/promise';
|
||||||
|
|
||||||
|
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
|
||||||
import * as modelModule from './model';
|
import * as modelModule from './model';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Providers for validators to be used for {@link Control}s in a form.
|
* Providers for validators to be used for {@link Control}s in a form.
|
||||||
|
@ -16,7 +19,7 @@ import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
||||||
* {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'}
|
* {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'}
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const NG_VALIDATORS: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken("NgValidators");
|
export const NG_VALIDATORS: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken('NgValidators');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Providers for asynchronous validators to be used for {@link Control}s
|
* Providers for asynchronous validators to be used for {@link Control}s
|
||||||
|
@ -29,7 +32,7 @@ export const NG_VALIDATORS: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken("Ng
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const NG_ASYNC_VALIDATORS: OpaqueToken =
|
export const NG_ASYNC_VALIDATORS: OpaqueToken =
|
||||||
/*@ts2dart_const*/ new OpaqueToken("NgAsyncValidators");
|
/*@ts2dart_const*/ new OpaqueToken('NgAsyncValidators');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a set of validators used by form controls.
|
* Provides a set of validators used by form controls.
|
||||||
|
@ -50,9 +53,9 @@ export class Validators {
|
||||||
* Validator that requires controls to have a non-empty value.
|
* Validator that requires controls to have a non-empty value.
|
||||||
*/
|
*/
|
||||||
static required(control: modelModule.AbstractControl): {[key: string]: boolean} {
|
static required(control: modelModule.AbstractControl): {[key: string]: boolean} {
|
||||||
return isBlank(control.value) || (isString(control.value) && control.value == "") ?
|
return isBlank(control.value) || (isString(control.value) && control.value == '') ?
|
||||||
{"required": true} :
|
{'required': true} :
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,8 +66,8 @@ export class Validators {
|
||||||
if (isPresent(Validators.required(control))) return null;
|
if (isPresent(Validators.required(control))) return null;
|
||||||
var v: string = control.value;
|
var v: string = control.value;
|
||||||
return v.length < minLength ?
|
return v.length < minLength ?
|
||||||
{"minlength": {"requiredLength": minLength, "actualLength": v.length}} :
|
{'minlength': {'requiredLength': minLength, 'actualLength': v.length}} :
|
||||||
null;
|
null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +79,8 @@ export class Validators {
|
||||||
if (isPresent(Validators.required(control))) return null;
|
if (isPresent(Validators.required(control))) return null;
|
||||||
var v: string = control.value;
|
var v: string = control.value;
|
||||||
return v.length > maxLength ?
|
return v.length > maxLength ?
|
||||||
{"maxlength": {"requiredLength": maxLength, "actualLength": v.length}} :
|
{'maxlength': {'requiredLength': maxLength, 'actualLength': v.length}} :
|
||||||
null;
|
null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +93,7 @@ export class Validators {
|
||||||
let regex = new RegExp(`^${pattern}$`);
|
let regex = new RegExp(`^${pattern}$`);
|
||||||
let v: string = control.value;
|
let v: string = control.value;
|
||||||
return regex.test(v) ? null :
|
return regex.test(v) ? null :
|
||||||
{"pattern": {"requiredPattern": `^${pattern}$`, "actualValue": v}};
|
{'pattern': {'requiredPattern': `^${pattern}$`, 'actualValue': v}};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,13 +132,13 @@ function _convertToPromise(obj: any): any {
|
||||||
return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj);
|
return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _executeValidators(control: modelModule.AbstractControl,
|
function _executeValidators(
|
||||||
validators: ValidatorFn[]): any[] {
|
control: modelModule.AbstractControl, validators: ValidatorFn[]): any[] {
|
||||||
return validators.map(v => v(control));
|
return validators.map(v => v(control));
|
||||||
}
|
}
|
||||||
|
|
||||||
function _executeAsyncValidators(control: modelModule.AbstractControl,
|
function _executeAsyncValidators(
|
||||||
validators: AsyncValidatorFn[]): any[] {
|
control: modelModule.AbstractControl, validators: AsyncValidatorFn[]): any[] {
|
||||||
return validators.map(v => v(control));
|
return validators.map(v => v(control));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,39 +10,32 @@
|
||||||
* Forms providers are not included in default providers; you must import these providers
|
* Forms providers are not included in default providers; you must import these providers
|
||||||
* explicitly.
|
* explicitly.
|
||||||
*/
|
*/
|
||||||
export {AbstractControl, Control, ControlGroup, ControlArray} from './forms/model';
|
import {Type} from '@angular/core';
|
||||||
|
|
||||||
|
import {RadioControlRegistry} from './forms/directives/radio_control_value_accessor';
|
||||||
|
import {FormBuilder} from './forms/form_builder';
|
||||||
|
|
||||||
|
export {FORM_DIRECTIVES, RadioButtonState} from './forms/directives';
|
||||||
export {AbstractControlDirective} from './forms/directives/abstract_control_directive';
|
export {AbstractControlDirective} from './forms/directives/abstract_control_directive';
|
||||||
export {Form} from './forms/directives/form_interface';
|
export {CheckboxControlValueAccessor} from './forms/directives/checkbox_value_accessor';
|
||||||
export {ControlContainer} from './forms/directives/control_container';
|
export {ControlContainer} from './forms/directives/control_container';
|
||||||
export {NgControlName} from './forms/directives/ng_control_name';
|
|
||||||
export {NgFormControl} from './forms/directives/ng_form_control';
|
|
||||||
export {NgModel} from './forms/directives/ng_model';
|
|
||||||
export {NgControl} from './forms/directives/ng_control';
|
|
||||||
export {NgControlGroup} from './forms/directives/ng_control_group';
|
|
||||||
export {NgFormModel} from './forms/directives/ng_form_model';
|
|
||||||
export {NgForm} from './forms/directives/ng_form';
|
|
||||||
export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './forms/directives/control_value_accessor';
|
export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './forms/directives/control_value_accessor';
|
||||||
export {DefaultValueAccessor} from './forms/directives/default_value_accessor';
|
export {DefaultValueAccessor} from './forms/directives/default_value_accessor';
|
||||||
|
export {Form} from './forms/directives/form_interface';
|
||||||
|
export {NgControl} from './forms/directives/ng_control';
|
||||||
|
export {NgControlGroup} from './forms/directives/ng_control_group';
|
||||||
|
export {NgControlName} from './forms/directives/ng_control_name';
|
||||||
export {NgControlStatus} from './forms/directives/ng_control_status';
|
export {NgControlStatus} from './forms/directives/ng_control_status';
|
||||||
export {CheckboxControlValueAccessor} from './forms/directives/checkbox_value_accessor';
|
export {NgForm} from './forms/directives/ng_form';
|
||||||
export {
|
export {NgFormControl} from './forms/directives/ng_form_control';
|
||||||
NgSelectOption,
|
export {NgFormModel} from './forms/directives/ng_form_model';
|
||||||
SelectControlValueAccessor
|
export {NgModel} from './forms/directives/ng_model';
|
||||||
} from './forms/directives/select_control_value_accessor';
|
export {NgSelectOption, SelectControlValueAccessor} from './forms/directives/select_control_value_accessor';
|
||||||
export {FORM_DIRECTIVES, RadioButtonState} from './forms/directives';
|
export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator, Validator} from './forms/directives/validators';
|
||||||
export {NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validators} from './forms/validators';
|
|
||||||
export {
|
|
||||||
RequiredValidator,
|
|
||||||
MinLengthValidator,
|
|
||||||
MaxLengthValidator,
|
|
||||||
PatternValidator,
|
|
||||||
Validator
|
|
||||||
} from './forms/directives/validators';
|
|
||||||
export {FormBuilder} from './forms/form_builder';
|
export {FormBuilder} from './forms/form_builder';
|
||||||
import {FormBuilder} from './forms/form_builder';
|
export {AbstractControl, Control, ControlArray, ControlGroup} from './forms/model';
|
||||||
import {RadioControlRegistry} from './forms/directives/radio_control_value_accessor';
|
export {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from './forms/validators';
|
||||||
import {Type} from '@angular/core';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shorthand set of providers used for building Angular forms.
|
* Shorthand set of providers used for building Angular forms.
|
||||||
|
|
|
@ -1,60 +1,37 @@
|
||||||
import {Type} from '@angular/core';
|
import {Type} from '@angular/core';
|
||||||
import {NgControlName} from './directives/ng_control_name';
|
|
||||||
import {NgFormControl} from './directives/ng_form_control';
|
|
||||||
import {NgModel} from './directives/ng_model';
|
|
||||||
import {NgControlGroup} from './directives/ng_control_group';
|
|
||||||
import {NgFormModel} from './directives/ng_form_model';
|
|
||||||
import {NgForm} from './directives/ng_form';
|
|
||||||
import {DefaultValueAccessor} from './directives/default_value_accessor';
|
|
||||||
import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||||
|
import {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||||
|
import {NgControlGroup} from './directives/ng_control_group';
|
||||||
|
import {NgControlName} from './directives/ng_control_name';
|
||||||
|
import {NgControlStatus} from './directives/ng_control_status';
|
||||||
|
import {NgForm} from './directives/ng_form';
|
||||||
|
import {NgFormControl} from './directives/ng_form_control';
|
||||||
|
import {NgFormModel} from './directives/ng_form_model';
|
||||||
|
import {NgModel} from './directives/ng_model';
|
||||||
import {NumberValueAccessor} from './directives/number_value_accessor';
|
import {NumberValueAccessor} from './directives/number_value_accessor';
|
||||||
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||||
import {NgControlStatus} from './directives/ng_control_status';
|
import {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
||||||
import {
|
import {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
||||||
SelectControlValueAccessor,
|
import {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators';
|
||||||
NgSelectOption
|
|
||||||
} from './directives/select_control_value_accessor';
|
|
||||||
import {
|
|
||||||
SelectMultipleControlValueAccessor,
|
|
||||||
NgSelectMultipleOption
|
|
||||||
} from './directives/select_multiple_control_value_accessor';
|
|
||||||
import {
|
|
||||||
RequiredValidator,
|
|
||||||
MinLengthValidator,
|
|
||||||
MaxLengthValidator,
|
|
||||||
PatternValidator
|
|
||||||
} from './directives/validators';
|
|
||||||
|
|
||||||
export {NgControlName} from './directives/ng_control_name';
|
|
||||||
export {NgFormControl} from './directives/ng_form_control';
|
|
||||||
export {NgModel} from './directives/ng_model';
|
|
||||||
export {NgControlGroup} from './directives/ng_control_group';
|
|
||||||
export {NgFormModel} from './directives/ng_form_model';
|
|
||||||
export {NgForm} from './directives/ng_form';
|
|
||||||
export {DefaultValueAccessor} from './directives/default_value_accessor';
|
|
||||||
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||||
export {
|
|
||||||
RadioControlValueAccessor,
|
|
||||||
RadioButtonState
|
|
||||||
} from './directives/radio_control_value_accessor';
|
|
||||||
export {NumberValueAccessor} from './directives/number_value_accessor';
|
|
||||||
export {NgControlStatus} from './directives/ng_control_status';
|
|
||||||
export {
|
|
||||||
SelectControlValueAccessor,
|
|
||||||
NgSelectOption
|
|
||||||
} from './directives/select_control_value_accessor';
|
|
||||||
export {
|
|
||||||
SelectMultipleControlValueAccessor,
|
|
||||||
NgSelectMultipleOption
|
|
||||||
} from './directives/select_multiple_control_value_accessor';
|
|
||||||
export {
|
|
||||||
RequiredValidator,
|
|
||||||
MinLengthValidator,
|
|
||||||
MaxLengthValidator,
|
|
||||||
PatternValidator
|
|
||||||
} from './directives/validators';
|
|
||||||
export {NgControl} from './directives/ng_control';
|
|
||||||
export {ControlValueAccessor} from './directives/control_value_accessor';
|
export {ControlValueAccessor} from './directives/control_value_accessor';
|
||||||
|
export {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||||
|
export {NgControl} from './directives/ng_control';
|
||||||
|
export {NgControlGroup} from './directives/ng_control_group';
|
||||||
|
export {NgControlName} from './directives/ng_control_name';
|
||||||
|
export {NgControlStatus} from './directives/ng_control_status';
|
||||||
|
export {NgForm} from './directives/ng_form';
|
||||||
|
export {NgFormControl} from './directives/ng_form_control';
|
||||||
|
export {NgFormModel} from './directives/ng_form_model';
|
||||||
|
export {NgModel} from './directives/ng_model';
|
||||||
|
export {NumberValueAccessor} from './directives/number_value_accessor';
|
||||||
|
export {RadioButtonState, RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||||
|
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';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -74,26 +51,13 @@ export {ControlValueAccessor} from './directives/control_value_accessor';
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const FORM_DIRECTIVES: Type[] = /*@ts2dart_const*/[
|
export const FORM_DIRECTIVES: Type[] = /*@ts2dart_const*/[
|
||||||
NgControlName,
|
NgControlName, NgControlGroup,
|
||||||
NgControlGroup,
|
|
||||||
|
|
||||||
NgFormControl,
|
NgFormControl, NgModel, NgFormModel, NgForm,
|
||||||
NgModel,
|
|
||||||
NgFormModel,
|
|
||||||
NgForm,
|
|
||||||
|
|
||||||
NgSelectOption,
|
NgSelectOption, NgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor,
|
||||||
NgSelectMultipleOption,
|
CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor,
|
||||||
DefaultValueAccessor,
|
RadioControlValueAccessor, NgControlStatus,
|
||||||
NumberValueAccessor,
|
|
||||||
CheckboxControlValueAccessor,
|
|
||||||
SelectControlValueAccessor,
|
|
||||||
SelectMultipleControlValueAccessor,
|
|
||||||
RadioControlValueAccessor,
|
|
||||||
NgControlStatus,
|
|
||||||
|
|
||||||
RequiredValidator,
|
RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator
|
||||||
MinLengthValidator,
|
|
||||||
MaxLengthValidator,
|
|
||||||
PatternValidator
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {AbstractControl} from '../model';
|
|
||||||
import {isPresent} from '../../facade/lang';
|
|
||||||
import {unimplemented} from '../../facade/exceptions';
|
import {unimplemented} from '../../facade/exceptions';
|
||||||
|
import {isPresent} from '../../facade/lang';
|
||||||
|
import {AbstractControl} from '../model';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for control directives.
|
* Base class for control directives.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {Directive, Renderer, ElementRef, forwardRef} from '@angular/core';
|
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
export const CHECKBOX_VALUE_ACCESSOR: any = /*@ts2dart_const*/ {
|
export const CHECKBOX_VALUE_ACCESSOR: any = /*@ts2dart_const*/ {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {Form} from './form_interface';
|
|
||||||
import {AbstractControlDirective} from './abstract_control_directive';
|
import {AbstractControlDirective} from './abstract_control_directive';
|
||||||
|
import {Form} from './form_interface';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A directive that contains multiple {@link NgControl}s.
|
* A directive that contains multiple {@link NgControl}s.
|
||||||
|
|
|
@ -34,4 +34,4 @@ export interface ControlValueAccessor {
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const NG_VALUE_ACCESSOR: OpaqueToken =
|
export const NG_VALUE_ACCESSOR: OpaqueToken =
|
||||||
/*@ts2dart_const*/ new OpaqueToken("NgValueAccessor");
|
/*@ts2dart_const*/ new OpaqueToken('NgValueAccessor');
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {isBlank} from '../../facade/lang';
|
import {isBlank} from '../../facade/lang';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
export const DEFAULT_VALUE_ACCESSOR: any = /*@ts2dart_const*/
|
export const DEFAULT_VALUE_ACCESSOR: any = /*@ts2dart_const*/
|
||||||
/* @ts2dart_Provider */ {
|
/* @ts2dart_Provider */ {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import {Control, ControlGroup} from '../model';
|
||||||
|
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {NgControlGroup} from './ng_control_group';
|
import {NgControlGroup} from './ng_control_group';
|
||||||
import {Control, ControlGroup} from '../model';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface that {@link NgFormModel} and {@link NgForm} implement.
|
* An interface that {@link NgFormModel} and {@link NgForm} implement.
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import {unimplemented} from '../../facade/exceptions';
|
import {unimplemented} from '../../facade/exceptions';
|
||||||
|
|
||||||
import {ControlValueAccessor} from './control_value_accessor';
|
|
||||||
import {AbstractControlDirective} from './abstract_control_directive';
|
import {AbstractControlDirective} from './abstract_control_directive';
|
||||||
|
import {ControlValueAccessor} from './control_value_accessor';
|
||||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class that all control directive extend.
|
* A base class that all control directive extend.
|
||||||
* It binds a {@link Control} object to a DOM element.
|
* It binds a {@link Control} object to a DOM element.
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
import {
|
import {Directive, Host, Inject, OnDestroy, OnInit, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
||||||
OnInit,
|
|
||||||
OnDestroy,
|
|
||||||
Directive,
|
|
||||||
Optional,
|
|
||||||
Inject,
|
|
||||||
Host,
|
|
||||||
SkipSelf,
|
|
||||||
forwardRef,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
import {ControlContainer} from './control_container';
|
|
||||||
import {controlPath, composeValidators, composeAsyncValidators} from './shared';
|
|
||||||
import {ControlGroup} from '../model';
|
import {ControlGroup} from '../model';
|
||||||
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
|
import {ControlContainer} from './control_container';
|
||||||
import {Form} from './form_interface';
|
import {Form} from './form_interface';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {composeAsyncValidators, composeValidators, controlPath} from './shared';
|
||||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
|
|
||||||
export const controlGroupProvider: any =
|
export const controlGroupProvider: any =
|
||||||
|
@ -79,9 +71,10 @@ export class NgControlGroup extends ControlContainer implements OnInit,
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_parent: ControlContainer;
|
_parent: ControlContainer;
|
||||||
|
|
||||||
constructor(@Host() @SkipSelf() parent: ControlContainer,
|
constructor(
|
||||||
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
@Host() @SkipSelf() parent: ControlContainer,
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
this._parent = parent;
|
this._parent = parent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,14 @@
|
||||||
import {
|
import {Directive, Host, Inject, OnChanges, OnDestroy, Optional, Self, SimpleChanges, SkipSelf, forwardRef} from '@angular/core';
|
||||||
OnChanges,
|
|
||||||
OnDestroy,
|
|
||||||
SimpleChanges,
|
|
||||||
Directive,
|
|
||||||
forwardRef,
|
|
||||||
Host,
|
|
||||||
SkipSelf,
|
|
||||||
Inject,
|
|
||||||
Optional,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
import {ControlContainer} from './control_container';
|
|
||||||
import {NgControl} from './ng_control';
|
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
|
||||||
import {
|
|
||||||
controlPath,
|
|
||||||
composeValidators,
|
|
||||||
composeAsyncValidators,
|
|
||||||
isPropertyUpdated,
|
|
||||||
selectValueAccessor
|
|
||||||
} from './shared';
|
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
import {ValidatorFn, AsyncValidatorFn} 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 =
|
export const controlNameBinding: any =
|
||||||
|
@ -112,35 +96,37 @@ export class NgControlName extends NgControl implements OnChanges,
|
||||||
/* Array<Validator|Function> */ any[],
|
/* Array<Validator|Function> */ any[],
|
||||||
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
||||||
valueAccessors: ControlValueAccessor[]) {
|
valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (!this._added) {
|
if (!this._added) {
|
||||||
this.formDirective.addControl(this);
|
this.formDirective.addControl(this);
|
||||||
this._added = true;
|
this._added = true;
|
||||||
}
|
}
|
||||||
if (isPropertyUpdated(changes, this.viewModel)) {
|
if (isPropertyUpdated(changes, this.viewModel)) {
|
||||||
this.viewModel = this.model;
|
this.viewModel = this.model;
|
||||||
this.formDirective.updateModel(this, this.model);
|
this.formDirective.updateModel(this, this.model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void { this.formDirective.removeControl(this); }
|
ngOnDestroy(): void { this.formDirective.removeControl(this); }
|
||||||
|
|
||||||
viewToModelUpdate(newValue: any): void {
|
viewToModelUpdate(newValue: any): void {
|
||||||
this.viewModel = newValue;
|
this.viewModel = newValue;
|
||||||
ObservableWrapper.callEmit(this.update, newValue);
|
ObservableWrapper.callEmit(this.update, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
get path(): string[] { return controlPath(this.name, this._parent); }
|
get path(): string[] { return controlPath(this.name, this._parent); }
|
||||||
|
|
||||||
get formDirective(): any { return this._parent.formDirective; }
|
get formDirective(): any { return this._parent.formDirective; }
|
||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
get asyncValidator(): AsyncValidatorFn {
|
||||||
|
return composeAsyncValidators(this._asyncValidators);
|
||||||
|
}
|
||||||
|
|
||||||
get control(): Control { return this.formDirective.getControl(this); }
|
get control(): Control { return this.formDirective.getControl(this); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import {Directive, Self} from '@angular/core';
|
import {Directive, Self} from '@angular/core';
|
||||||
import {NgControl} from './ng_control';
|
|
||||||
import {isPresent} from '../../facade/lang';
|
import {isPresent} from '../../facade/lang';
|
||||||
|
|
||||||
|
import {NgControl} from './ng_control';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive automatically applied to Angular forms that sets CSS classes
|
* Directive automatically applied to Angular forms that sets CSS classes
|
||||||
* based on control status (valid/invalid/dirty/etc).
|
* based on control status (valid/invalid/dirty/etc).
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
import {Directive, forwardRef, Optional, Inject, Self} from '@angular/core';
|
import {Directive, Inject, Optional, Self, forwardRef} from '@angular/core';
|
||||||
import {
|
|
||||||
PromiseWrapper,
|
import {EventEmitter, ObservableWrapper, PromiseWrapper} from '../../facade/async';
|
||||||
ObservableWrapper,
|
|
||||||
EventEmitter
|
|
||||||
} from '../../facade/async';
|
|
||||||
import {ListWrapper} from '../../facade/collection';
|
import {ListWrapper} from '../../facade/collection';
|
||||||
import {isPresent} from '../../facade/lang';
|
import {isPresent} from '../../facade/lang';
|
||||||
import {NgControl} from './ng_control';
|
import {AbstractControl, Control, ControlGroup} from '../model';
|
||||||
import {Form} from './form_interface';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
import {NgControlGroup} from './ng_control_group';
|
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {AbstractControl, ControlGroup, Control} from '../model';
|
import {Form} from './form_interface';
|
||||||
import {setUpControl, setUpControlGroup, composeValidators, composeAsyncValidators} from './shared';
|
import {NgControl} from './ng_control';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {NgControlGroup} from './ng_control_group';
|
||||||
|
import {composeAsyncValidators, composeValidators, setUpControl, setUpControlGroup} from './shared';
|
||||||
|
|
||||||
export const formDirectiveProvider: any =
|
export const formDirectiveProvider: any =
|
||||||
/*@ts2dart_const*/ {provide: ControlContainer, useExisting: forwardRef(() => NgForm)};
|
/*@ts2dart_const*/ {provide: ControlContainer, useExisting: forwardRef(() => NgForm)};
|
||||||
|
@ -93,11 +91,12 @@ export class NgForm extends ControlContainer implements Form {
|
||||||
form: ControlGroup;
|
form: ControlGroup;
|
||||||
ngSubmit = new EventEmitter();
|
ngSubmit = new EventEmitter();
|
||||||
|
|
||||||
constructor(@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
constructor(
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
||||||
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
this.form = new ControlGroup({}, null, composeValidators(validators),
|
this.form = new ControlGroup(
|
||||||
composeAsyncValidators(asyncValidators));
|
{}, null, composeValidators(validators), composeAsyncValidators(asyncValidators));
|
||||||
}
|
}
|
||||||
|
|
||||||
get submitted(): boolean { return this._submitted; }
|
get submitted(): boolean { return this._submitted; }
|
||||||
|
|
|
@ -1,28 +1,14 @@
|
||||||
import {
|
import {Directive, Inject, OnChanges, Optional, Self, SimpleChanges, forwardRef} from '@angular/core';
|
||||||
OnChanges,
|
|
||||||
SimpleChanges,
|
|
||||||
Directive,
|
|
||||||
forwardRef,
|
|
||||||
Inject,
|
|
||||||
Optional,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import {StringMapWrapper} from '../../facade/collection';
|
|
||||||
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
|
import {StringMapWrapper} from '../../facade/collection';
|
||||||
import {NgControl} from './ng_control';
|
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {
|
import {NgControl} from './ng_control';
|
||||||
setUpControl,
|
import {composeAsyncValidators, composeValidators, isPropertyUpdated, selectValueAccessor, setUpControl} from './shared';
|
||||||
composeValidators,
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
composeAsyncValidators,
|
|
||||||
isPropertyUpdated,
|
|
||||||
selectValueAccessor
|
|
||||||
} from './shared';
|
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
|
||||||
|
|
||||||
export const formControlBinding: any =
|
export const formControlBinding: any =
|
||||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||||
|
@ -98,35 +84,37 @@ export class NgFormControl extends NgControl implements OnChanges {
|
||||||
/* Array<Validator|Function> */ any[],
|
/* Array<Validator|Function> */ any[],
|
||||||
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
||||||
valueAccessors: ControlValueAccessor[]) {
|
valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
if (this._isControlChanged(changes)) {
|
if (this._isControlChanged(changes)) {
|
||||||
setUpControl(this.form, this);
|
setUpControl(this.form, this);
|
||||||
this.form.updateValueAndValidity({emitEvent: false});
|
this.form.updateValueAndValidity({emitEvent: false});
|
||||||
}
|
}
|
||||||
if (isPropertyUpdated(changes, this.viewModel)) {
|
if (isPropertyUpdated(changes, this.viewModel)) {
|
||||||
this.form.updateValue(this.model);
|
this.form.updateValue(this.model);
|
||||||
this.viewModel = this.model;
|
this.viewModel = this.model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get path(): string[] { return []; }
|
get path(): string[] { return []; }
|
||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
get asyncValidator(): AsyncValidatorFn {
|
||||||
|
return composeAsyncValidators(this._asyncValidators);
|
||||||
|
}
|
||||||
|
|
||||||
get control(): Control { return this.form; }
|
get control(): Control { return this.form; }
|
||||||
|
|
||||||
viewToModelUpdate(newValue: any): void {
|
viewToModelUpdate(newValue: any): void {
|
||||||
this.viewModel = newValue;
|
this.viewModel = newValue;
|
||||||
ObservableWrapper.callEmit(this.update, newValue);
|
ObservableWrapper.callEmit(this.update, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isControlChanged(changes: {[key: string]: any}): boolean {
|
private _isControlChanged(changes: {[key: string]: any}): boolean {
|
||||||
return StringMapWrapper.contains(changes, "form");
|
return StringMapWrapper.contains(changes, 'form');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,17 @@
|
||||||
import {
|
import {Directive, Inject, OnChanges, Optional, Self, SimpleChanges, forwardRef} from '@angular/core';
|
||||||
SimpleChanges,
|
|
||||||
OnChanges,
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
Directive,
|
|
||||||
forwardRef,
|
|
||||||
Inject,
|
|
||||||
Optional,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
import {isBlank} from '../../facade/lang';
|
|
||||||
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
|
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
|
||||||
import {BaseException} from '../../facade/exceptions';
|
import {BaseException} from '../../facade/exceptions';
|
||||||
import {ObservableWrapper, EventEmitter} from '../../facade/async';
|
import {isBlank} from '../../facade/lang';
|
||||||
import {NgControl} from './ng_control';
|
import {Control, ControlGroup} from '../model';
|
||||||
import {NgControlGroup} from './ng_control_group';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from '../validators';
|
||||||
|
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {Form} from './form_interface';
|
import {Form} from './form_interface';
|
||||||
import {Control, ControlGroup} from '../model';
|
import {NgControl} from './ng_control';
|
||||||
import {setUpControl, setUpControlGroup, composeValidators, composeAsyncValidators} from './shared';
|
import {NgControlGroup} from './ng_control_group';
|
||||||
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {composeAsyncValidators, composeValidators, setUpControl, setUpControlGroup} from './shared';
|
||||||
|
|
||||||
export const formDirectiveProvider: any =
|
export const formDirectiveProvider: any =
|
||||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||||
|
@ -115,14 +109,15 @@ export class NgFormModel extends ControlContainer implements Form,
|
||||||
directives: NgControl[] = [];
|
directives: NgControl[] = [];
|
||||||
ngSubmit = new EventEmitter();
|
ngSubmit = new EventEmitter();
|
||||||
|
|
||||||
constructor(@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
constructor(
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
this._checkFormPresent();
|
this._checkFormPresent();
|
||||||
if (StringMapWrapper.contains(changes, "form")) {
|
if (StringMapWrapper.contains(changes, 'form')) {
|
||||||
var sync = composeValidators(this._validators);
|
var sync = composeValidators(this._validators);
|
||||||
this.form.validator = Validators.compose([this.form.validator, sync]);
|
this.form.validator = Validators.compose([this.form.validator, sync]);
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
import {
|
import {Directive, Inject, OnChanges, Optional, Self, SimpleChanges, forwardRef} from '@angular/core';
|
||||||
OnChanges,
|
|
||||||
SimpleChanges,
|
|
||||||
Directive,
|
|
||||||
forwardRef,
|
|
||||||
Inject,
|
|
||||||
Optional,
|
|
||||||
Self
|
|
||||||
} from '@angular/core';
|
|
||||||
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
|
import {Control} from '../model';
|
||||||
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {Control} from '../model';
|
import {composeAsyncValidators, composeValidators, isPropertyUpdated, selectValueAccessor, setUpControl} from './shared';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
import {
|
|
||||||
setUpControl,
|
|
||||||
isPropertyUpdated,
|
|
||||||
selectValueAccessor,
|
|
||||||
composeValidators,
|
|
||||||
composeAsyncValidators
|
|
||||||
} from './shared';
|
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
|
||||||
|
|
||||||
export const formControlBinding: any =
|
export const formControlBinding: any =
|
||||||
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
/*@ts2dart_const*/ /* @ts2dart_Provider */ {
|
||||||
|
@ -70,33 +58,35 @@ export class NgModel extends NgControl implements OnChanges {
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[],
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[],
|
||||||
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
|
||||||
valueAccessors: ControlValueAccessor[]) {
|
valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (!this._added) {
|
if (!this._added) {
|
||||||
setUpControl(this._control, this);
|
setUpControl(this._control, this);
|
||||||
this._control.updateValueAndValidity({emitEvent: false});
|
this._control.updateValueAndValidity({emitEvent: false});
|
||||||
this._added = true;
|
this._added = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPropertyUpdated(changes, this.viewModel)) {
|
if (isPropertyUpdated(changes, this.viewModel)) {
|
||||||
this._control.updateValue(this.model);
|
this._control.updateValue(this.model);
|
||||||
this.viewModel = this.model;
|
this.viewModel = this.model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get control(): Control { return this._control; }
|
get control(): Control { return this._control; }
|
||||||
|
|
||||||
get path(): string[] { return []; }
|
get path(): string[] { return []; }
|
||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
get asyncValidator(): AsyncValidatorFn {
|
||||||
|
return composeAsyncValidators(this._asyncValidators);
|
||||||
|
}
|
||||||
|
|
||||||
viewToModelUpdate(newValue: any): void {
|
viewToModelUpdate(newValue: any): void {
|
||||||
this.viewModel = newValue;
|
this.viewModel = newValue;
|
||||||
ObservableWrapper.callEmit(this.update, newValue);
|
ObservableWrapper.callEmit(this.update, newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {AbstractControl} from '../model';
|
import {AbstractControl} from '../model';
|
||||||
import {Validator, ValidatorFn, AsyncValidatorFn} from './validators';
|
|
||||||
|
import {AsyncValidatorFn, Validator, ValidatorFn} from './validators';
|
||||||
|
|
||||||
export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn {
|
export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn {
|
||||||
if ((<Validator>validator).validate !== undefined) {
|
if ((<Validator>validator).validate !== undefined) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {NumberWrapper} from '../../facade/lang';
|
import {NumberWrapper} from '../../facade/lang';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
export const NUMBER_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
export const NUMBER_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
import {
|
import {Directive, ElementRef, Injectable, Injector, Input, OnDestroy, OnInit, Renderer, forwardRef} from '@angular/core';
|
||||||
Directive,
|
|
||||||
ElementRef,
|
|
||||||
Renderer,
|
|
||||||
forwardRef,
|
|
||||||
Input,
|
|
||||||
OnInit,
|
|
||||||
OnDestroy,
|
|
||||||
Injector,
|
|
||||||
Injectable
|
|
||||||
} from '@angular/core';
|
|
||||||
import {isPresent} from '../../facade/lang';
|
|
||||||
import {ListWrapper} from '../../facade/collection';
|
import {ListWrapper} from '../../facade/collection';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
import {isPresent} from '../../facade/lang';
|
||||||
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
|
|
||||||
export const RADIO_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
export const RADIO_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
||||||
|
@ -49,10 +41,10 @@ export class RadioControlRegistry {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isSameGroup(controlPair:[NgControl, RadioControlValueAccessor],
|
private _isSameGroup(
|
||||||
accessor: RadioControlValueAccessor) {
|
controlPair: [NgControl, RadioControlValueAccessor], accessor: RadioControlValueAccessor) {
|
||||||
return controlPair[0].control.root === accessor._control.control.root &&
|
return controlPair[0].control.root === accessor._control.control.root &&
|
||||||
controlPair[1].name === accessor.name;
|
controlPair[1].name === accessor.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +94,9 @@ export class RadioControlValueAccessor implements ControlValueAccessor,
|
||||||
onChange = () => {};
|
onChange = () => {};
|
||||||
onTouched = () => {};
|
onTouched = () => {};
|
||||||
|
|
||||||
constructor(private _renderer: Renderer, private _elementRef: ElementRef,
|
constructor(
|
||||||
private _registry: RadioControlRegistry, private _injector: Injector) {}
|
private _renderer: Renderer, private _elementRef: ElementRef,
|
||||||
|
private _registry: RadioControlRegistry, private _injector: Injector) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this._control = this._injector.get(NgControl);
|
this._control = this._injector.get(NgControl);
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
import {
|
import {Directive, ElementRef, Host, Input, OnDestroy, Optional, Renderer, forwardRef} from '@angular/core';
|
||||||
Directive,
|
|
||||||
Renderer,
|
|
||||||
forwardRef,
|
|
||||||
ElementRef,
|
|
||||||
Input,
|
|
||||||
Host,
|
|
||||||
OnDestroy,
|
|
||||||
Optional
|
|
||||||
} from '@angular/core';
|
|
||||||
import {
|
|
||||||
StringWrapper,
|
|
||||||
isPrimitive,
|
|
||||||
isPresent,
|
|
||||||
isBlank,
|
|
||||||
looseIdentical
|
|
||||||
} from '../../facade/lang';
|
|
||||||
import {MapWrapper} from '../../facade/collection';
|
|
||||||
|
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
import {MapWrapper} from '../../facade/collection';
|
||||||
|
import {StringWrapper, isBlank, isPresent, isPrimitive, looseIdentical} from '../../facade/lang';
|
||||||
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
export const SELECT_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
export const SELECT_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
@ -27,12 +13,12 @@ export const SELECT_VALUE_ACCESSOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider
|
||||||
|
|
||||||
function _buildValueString(id: string, value: any): string {
|
function _buildValueString(id: string, value: any): string {
|
||||||
if (isBlank(id)) return `${value}`;
|
if (isBlank(id)) return `${value}`;
|
||||||
if (!isPrimitive(value)) value = "Object";
|
if (!isPrimitive(value)) value = 'Object';
|
||||||
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _extractId(valueString: string): string {
|
function _extractId(valueString: string): string {
|
||||||
return valueString.split(":")[0];
|
return valueString.split(':')[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,8 +98,9 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
|
||||||
export class NgSelectOption implements OnDestroy {
|
export class NgSelectOption implements OnDestroy {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
constructor(private _element: ElementRef, private _renderer: Renderer,
|
constructor(
|
||||||
@Optional() @Host() private _select: SelectControlValueAccessor) {
|
private _element: ElementRef, private _renderer: Renderer,
|
||||||
|
@Optional() @Host() private _select: SelectControlValueAccessor) {
|
||||||
if (isPresent(this._select)) this.id = this._select._registerOption();
|
if (isPresent(this._select)) this.id = this._select._registerOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
import {
|
import {Directive, ElementRef, Host, Input, OnDestroy, Optional, Renderer, forwardRef} from '@angular/core';
|
||||||
Input,
|
|
||||||
Directive,
|
|
||||||
ElementRef,
|
|
||||||
Renderer,
|
|
||||||
Optional,
|
|
||||||
Host,
|
|
||||||
OnDestroy,
|
|
||||||
forwardRef
|
|
||||||
} from "@angular/core";
|
|
||||||
import {
|
|
||||||
isBlank,
|
|
||||||
isPrimitive,
|
|
||||||
StringWrapper,
|
|
||||||
isPresent,
|
|
||||||
looseIdentical,
|
|
||||||
isString
|
|
||||||
} from '../../facade/lang';
|
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
|
||||||
import {MapWrapper} from '../../facade/collection';
|
import {MapWrapper} from '../../facade/collection';
|
||||||
|
import {StringWrapper, isBlank, isPresent, isPrimitive, isString, looseIdentical} from '../../facade/lang';
|
||||||
|
|
||||||
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
|
|
||||||
const SELECT_MULTIPLE_VALUE_ACCESSOR = {
|
const SELECT_MULTIPLE_VALUE_ACCESSOR = {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
@ -28,12 +14,12 @@ const SELECT_MULTIPLE_VALUE_ACCESSOR = {
|
||||||
function _buildValueString(id: string, value: any): string {
|
function _buildValueString(id: string, value: any): string {
|
||||||
if (isBlank(id)) return `${value}`;
|
if (isBlank(id)) return `${value}`;
|
||||||
if (isString(value)) value = `'${value}'`;
|
if (isString(value)) value = `'${value}'`;
|
||||||
if (!isPrimitive(value)) value = "Object";
|
if (!isPrimitive(value)) value = 'Object';
|
||||||
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _extractId(valueString: string): string {
|
function _extractId(valueString: string): string {
|
||||||
return valueString.split(":")[0];
|
return valueString.split(':')[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mock interface for HTML Options */
|
/** Mock interface for HTML Options */
|
||||||
|
@ -74,9 +60,7 @@ export class SelectMultipleControlValueAccessor implements ControlValueAccessor
|
||||||
let values: Array<any> = <Array<any>>value;
|
let values: Array<any> = <Array<any>>value;
|
||||||
// convert values to ids
|
// convert values to ids
|
||||||
let ids = values.map((v) => this._getOptionId(v));
|
let ids = values.map((v) => this._getOptionId(v));
|
||||||
this._optionMap.forEach((opt, o) => {
|
this._optionMap.forEach((opt, o) => { opt._setSelected(ids.indexOf(o.toString()) > -1); });
|
||||||
opt._setSelected(ids.indexOf(o.toString()) > -1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
registerOnChange(fn: (value: any) => any): void {
|
registerOnChange(fn: (value: any) => any): void {
|
||||||
|
@ -108,7 +92,7 @@ export class SelectMultipleControlValueAccessor implements ControlValueAccessor
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_registerOption(value: NgSelectMultipleOption): string {
|
_registerOption(value: NgSelectMultipleOption): string {
|
||||||
let id:string = (this._idCounter++).toString();
|
let id: string = (this._idCounter++).toString();
|
||||||
this._optionMap.set(id, value);
|
this._optionMap.set(id, value);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -145,8 +129,9 @@ export class NgSelectMultipleOption implements OnDestroy {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_value: any;
|
_value: any;
|
||||||
|
|
||||||
constructor(private _element: ElementRef, private _renderer: Renderer,
|
constructor(
|
||||||
@Optional() @Host() private _select: SelectMultipleControlValueAccessor) {
|
private _element: ElementRef, private _renderer: Renderer,
|
||||||
|
@Optional() @Host() private _select: SelectMultipleControlValueAccessor) {
|
||||||
if (isPresent(this._select)) {
|
if (isPresent(this._select)) {
|
||||||
this.id = this._select._registerOption(this);
|
this.id = this._select._registerOption(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
|
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
|
||||||
import {isBlank, isPresent, looseIdentical, hasConstructor} from '../../facade/lang';
|
|
||||||
import {BaseException} from '../../facade/exceptions';
|
import {BaseException} from '../../facade/exceptions';
|
||||||
|
import {hasConstructor, isBlank, isPresent, looseIdentical} from '../../facade/lang';
|
||||||
import {ControlContainer} from './control_container';
|
|
||||||
import {NgControl} from './ng_control';
|
|
||||||
import {AbstractControlDirective} from './abstract_control_directive';
|
|
||||||
import {NgControlGroup} from './ng_control_group';
|
|
||||||
import {Control, ControlGroup} from '../model';
|
import {Control, ControlGroup} from '../model';
|
||||||
import {Validators} from '../validators';
|
import {Validators} from '../validators';
|
||||||
|
|
||||||
|
import {AbstractControlDirective} from './abstract_control_directive';
|
||||||
|
import {CheckboxControlValueAccessor} from './checkbox_value_accessor';
|
||||||
|
import {ControlContainer} from './control_container';
|
||||||
import {ControlValueAccessor} from './control_value_accessor';
|
import {ControlValueAccessor} from './control_value_accessor';
|
||||||
import {DefaultValueAccessor} from './default_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 {NumberValueAccessor} from './number_value_accessor';
|
||||||
import {CheckboxControlValueAccessor} from './checkbox_value_accessor';
|
|
||||||
import {SelectControlValueAccessor} from './select_control_value_accessor';
|
|
||||||
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
||||||
import {normalizeValidator, normalizeAsyncValidator} from './normalize_validator';
|
import {SelectControlValueAccessor} from './select_control_value_accessor';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
|
|
||||||
|
|
||||||
export function controlPath(name: string, parent: ControlContainer): string[] {
|
export function controlPath(name: string, parent: ControlContainer): string[] {
|
||||||
|
@ -25,8 +25,8 @@ export function controlPath(name: string, parent: ControlContainer): string[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setUpControl(control: Control, dir: NgControl): void {
|
export function setUpControl(control: Control, dir: NgControl): void {
|
||||||
if (isBlank(control)) _throwError(dir, "Cannot find control");
|
if (isBlank(control)) _throwError(dir, 'Cannot find control');
|
||||||
if (isBlank(dir.valueAccessor)) _throwError(dir, "No value accessor for");
|
if (isBlank(dir.valueAccessor)) _throwError(dir, 'No value accessor for');
|
||||||
|
|
||||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||||
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||||
|
@ -47,13 +47,13 @@ export function setUpControl(control: Control, dir: NgControl): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
|
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
|
||||||
if (isBlank(control)) _throwError(dir, "Cannot find control");
|
if (isBlank(control)) _throwError(dir, 'Cannot find control');
|
||||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||||
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _throwError(dir: AbstractControlDirective, message: string): void {
|
function _throwError(dir: AbstractControlDirective, message: string): void {
|
||||||
var path = dir.path.join(" -> ");
|
var path = dir.path.join(' -> ');
|
||||||
throw new BaseException(`${message} '${path}'`);
|
throw new BaseException(`${message} '${path}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,23 +61,23 @@ export function composeValidators(validators: /* Array<Validator|Function> */ an
|
||||||
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
|
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function composeAsyncValidators(
|
export function composeAsyncValidators(validators: /* Array<Validator|Function> */ any[]):
|
||||||
validators: /* Array<Validator|Function> */ any[]): AsyncValidatorFn {
|
AsyncValidatorFn {
|
||||||
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
|
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
||||||
if (!StringMapWrapper.contains(changes, "model")) return false;
|
if (!StringMapWrapper.contains(changes, 'model')) return false;
|
||||||
var change = changes["model"];
|
var change = changes['model'];
|
||||||
|
|
||||||
if (change.isFirstChange()) return true;
|
if (change.isFirstChange()) return true;
|
||||||
return !looseIdentical(viewModel, change.currentValue);
|
return !looseIdentical(viewModel, change.currentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
|
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
|
||||||
export function selectValueAccessor(dir: NgControl,
|
export function selectValueAccessor(
|
||||||
valueAccessors: ControlValueAccessor[]): ControlValueAccessor {
|
dir: NgControl, valueAccessors: ControlValueAccessor[]): ControlValueAccessor {
|
||||||
if (isBlank(valueAccessors)) return null;
|
if (isBlank(valueAccessors)) return null;
|
||||||
|
|
||||||
var defaultAccessor: ControlValueAccessor;
|
var defaultAccessor: ControlValueAccessor;
|
||||||
|
@ -87,17 +87,17 @@ export function selectValueAccessor(dir: NgControl,
|
||||||
if (hasConstructor(v, DefaultValueAccessor)) {
|
if (hasConstructor(v, DefaultValueAccessor)) {
|
||||||
defaultAccessor = v;
|
defaultAccessor = v;
|
||||||
|
|
||||||
} else if (hasConstructor(v, CheckboxControlValueAccessor) ||
|
} else if (
|
||||||
hasConstructor(v, NumberValueAccessor) ||
|
hasConstructor(v, CheckboxControlValueAccessor) || hasConstructor(v, NumberValueAccessor) ||
|
||||||
hasConstructor(v, SelectControlValueAccessor) ||
|
hasConstructor(v, SelectControlValueAccessor) ||
|
||||||
hasConstructor(v, RadioControlValueAccessor)) {
|
hasConstructor(v, RadioControlValueAccessor)) {
|
||||||
if (isPresent(builtinAccessor))
|
if (isPresent(builtinAccessor))
|
||||||
_throwError(dir, "More than one built-in value accessor matches");
|
_throwError(dir, 'More than one built-in value accessor matches');
|
||||||
builtinAccessor = v;
|
builtinAccessor = v;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (isPresent(customAccessor))
|
if (isPresent(customAccessor))
|
||||||
_throwError(dir, "More than one custom value accessor matches");
|
_throwError(dir, 'More than one custom value accessor matches');
|
||||||
customAccessor = v;
|
customAccessor = v;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -106,6 +106,6 @@ export function selectValueAccessor(dir: NgControl,
|
||||||
if (isPresent(builtinAccessor)) return builtinAccessor;
|
if (isPresent(builtinAccessor)) return builtinAccessor;
|
||||||
if (isPresent(defaultAccessor)) return defaultAccessor;
|
if (isPresent(defaultAccessor)) return defaultAccessor;
|
||||||
|
|
||||||
_throwError(dir, "No valid value accessor for");
|
_throwError(dir, 'No valid value accessor for');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import {forwardRef, Attribute, Directive} from '@angular/core';
|
import {Attribute, Directive, forwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {NumberWrapper} from '../../facade/lang';
|
import {NumberWrapper} from '../../facade/lang';
|
||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
|
||||||
import {AbstractControl} from '../model';
|
import {AbstractControl} from '../model';
|
||||||
|
import {NG_VALIDATORS, Validators} from '../validators';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ export const MIN_LENGTH_VALIDATOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*
|
||||||
export class MinLengthValidator implements Validator {
|
export class MinLengthValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute("minlength") minLength: string) {
|
constructor(@Attribute('minlength') minLength: string) {
|
||||||
this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10));
|
this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ export const MAX_LENGTH_VALIDATOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*
|
||||||
export class MaxLengthValidator implements Validator {
|
export class MaxLengthValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute("maxlength") maxLength: string) {
|
constructor(@Attribute('maxlength') maxLength: string) {
|
||||||
this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10));
|
this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +151,7 @@ export const PATTERN_VALIDATOR: any = /*@ts2dart_const*/ /*@ts2dart_Provider*/ {
|
||||||
export class PatternValidator implements Validator {
|
export class PatternValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute("pattern") pattern: string) {
|
constructor(@Attribute('pattern') pattern: string) {
|
||||||
this._validator = Validators.pattern(pattern);
|
this._validator = Validators.pattern(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
|
|
||||||
import {StringMapWrapper} from '../facade/collection';
|
import {StringMapWrapper} from '../facade/collection';
|
||||||
import {isPresent, isArray} from '../facade/lang';
|
import {isArray, isPresent} from '../facade/lang';
|
||||||
|
|
||||||
|
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
|
||||||
import * as modelModule from './model';
|
import * as modelModule from './model';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,21 +59,21 @@ export class FormBuilder {
|
||||||
*
|
*
|
||||||
* See the {@link ControlGroup} constructor for more details.
|
* See the {@link ControlGroup} constructor for more details.
|
||||||
*/
|
*/
|
||||||
group(controlsConfig: {[key: string]: any},
|
group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any} = null):
|
||||||
extra: {[key: string]: any} = null): modelModule.ControlGroup {
|
modelModule.ControlGroup {
|
||||||
var controls = this._reduceControls(controlsConfig);
|
var controls = this._reduceControls(controlsConfig);
|
||||||
var optionals = <{[key: string]: boolean}>(
|
var optionals = <{[key: string]: boolean}>(
|
||||||
isPresent(extra) ? StringMapWrapper.get(extra, "optionals") : null);
|
isPresent(extra) ? StringMapWrapper.get(extra, 'optionals') : null);
|
||||||
var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, "validator") : null;
|
var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, 'validator') : null;
|
||||||
var asyncValidator: AsyncValidatorFn =
|
var asyncValidator: AsyncValidatorFn =
|
||||||
isPresent(extra) ? StringMapWrapper.get(extra, "asyncValidator") : null;
|
isPresent(extra) ? StringMapWrapper.get(extra, 'asyncValidator') : null;
|
||||||
return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator);
|
return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`.
|
* Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`.
|
||||||
*/
|
*/
|
||||||
control(value: Object, validator: ValidatorFn = null,
|
control(value: Object, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null):
|
||||||
asyncValidator: AsyncValidatorFn = null): modelModule.Control {
|
modelModule.Control {
|
||||||
return new modelModule.Control(value, validator, asyncValidator);
|
return new modelModule.Control(value, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,15 +81,16 @@ export class FormBuilder {
|
||||||
* Construct an array of {@link Control}s from the given `controlsConfig` array of
|
* Construct an array of {@link Control}s from the given `controlsConfig` array of
|
||||||
* configuration, with the given optional `validator` and `asyncValidator`.
|
* configuration, with the given optional `validator` and `asyncValidator`.
|
||||||
*/
|
*/
|
||||||
array(controlsConfig: any[], validator: ValidatorFn = null,
|
array(
|
||||||
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray {
|
controlsConfig: any[], validator: ValidatorFn = null,
|
||||||
|
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray {
|
||||||
var controls = controlsConfig.map(c => this._createControl(c));
|
var controls = controlsConfig.map(c => this._createControl(c));
|
||||||
return new modelModule.ControlArray(controls, validator, asyncValidator);
|
return new modelModule.ControlArray(controls, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_reduceControls(controlsConfig: {[k: string]:
|
_reduceControls(controlsConfig: {[k: string]: any}):
|
||||||
any}): {[key: string]: modelModule.AbstractControl} {
|
{[key: string]: modelModule.AbstractControl} {
|
||||||
var controls: {[key: string]: modelModule.AbstractControl} = {};
|
var controls: {[key: string]: modelModule.AbstractControl} = {};
|
||||||
StringMapWrapper.forEach(controlsConfig, (controlConfig: any, controlName: string) => {
|
StringMapWrapper.forEach(controlsConfig, (controlConfig: any, controlName: string) => {
|
||||||
controls[controlName] = this._createControl(controlConfig);
|
controls[controlName] = this._createControl(controlConfig);
|
||||||
|
|
|
@ -1,48 +1,49 @@
|
||||||
import {isPresent, isBlank, normalizeBool} from '../facade/lang';
|
import {EventEmitter, Observable, ObservableWrapper} from '../facade/async';
|
||||||
import {Observable, EventEmitter, ObservableWrapper} from '../facade/async';
|
import {ListWrapper, StringMapWrapper} from '../facade/collection';
|
||||||
|
import {isBlank, isPresent, normalizeBool} from '../facade/lang';
|
||||||
import {PromiseWrapper} from '../facade/promise';
|
import {PromiseWrapper} from '../facade/promise';
|
||||||
import {StringMapWrapper, ListWrapper} from '../facade/collection';
|
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that a Control is valid, i.e. that no errors exist in the input value.
|
* Indicates that a Control is valid, i.e. that no errors exist in the input value.
|
||||||
*/
|
*/
|
||||||
export const VALID = "VALID";
|
export const VALID = 'VALID';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that a Control is invalid, i.e. that an error exists in the input value.
|
* Indicates that a Control is invalid, i.e. that an error exists in the input value.
|
||||||
*/
|
*/
|
||||||
export const INVALID = "INVALID";
|
export const INVALID = 'INVALID';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that a Control is pending, i.e. that async validation is occurring and
|
* Indicates that a Control is pending, i.e. that async validation is occurring and
|
||||||
* errors are not yet available for the input value.
|
* errors are not yet available for the input value.
|
||||||
*/
|
*/
|
||||||
export const PENDING = "PENDING";
|
export const PENDING = 'PENDING';
|
||||||
|
|
||||||
export function isControl(control: Object): boolean {
|
export function isControl(control: Object): boolean {
|
||||||
return control instanceof AbstractControl;
|
return control instanceof AbstractControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _find(control: AbstractControl, path: Array<string | number>| string) {
|
function _find(control: AbstractControl, path: Array<string|number>| string) {
|
||||||
if (isBlank(path)) return null;
|
if (isBlank(path)) return null;
|
||||||
|
|
||||||
if (!(path instanceof Array)) {
|
if (!(path instanceof Array)) {
|
||||||
path = (<string>path).split("/");
|
path = (<string>path).split('/');
|
||||||
}
|
}
|
||||||
if (path instanceof Array && ListWrapper.isEmpty(path)) return null;
|
if (path instanceof Array && ListWrapper.isEmpty(path)) return null;
|
||||||
|
|
||||||
return (<Array<string | number>>path)
|
return (<Array<string|number>>path).reduce((v, name) => {
|
||||||
.reduce((v, name) => {
|
if (v instanceof ControlGroup) {
|
||||||
if (v instanceof ControlGroup) {
|
return isPresent(v.controls[name]) ? v.controls[name] : null;
|
||||||
return isPresent(v.controls[name]) ? v.controls[name] : null;
|
} else if (v instanceof ControlArray) {
|
||||||
} else if (v instanceof ControlArray) {
|
var index = <number>name;
|
||||||
var index = <number>name;
|
return isPresent(v.at(index)) ? v.at(index) : null;
|
||||||
return isPresent(v.at(index)) ? v.at(index) : null;
|
} else {
|
||||||
} else {
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
}, control);
|
||||||
}, control);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toObservable(r: any): Observable<any> {
|
function toObservable(r: any): Observable<any> {
|
||||||
|
@ -62,7 +63,7 @@ export abstract class AbstractControl {
|
||||||
private _errors: {[key: string]: any};
|
private _errors: {[key: string]: any};
|
||||||
private _pristine: boolean = true;
|
private _pristine: boolean = true;
|
||||||
private _touched: boolean = false;
|
private _touched: boolean = false;
|
||||||
private _parent: ControlGroup | ControlArray;
|
private _parent: ControlGroup|ControlArray;
|
||||||
private _asyncValidationSubscription: any;
|
private _asyncValidationSubscription: any;
|
||||||
|
|
||||||
constructor(public validator: ValidatorFn, public asyncValidator: AsyncValidatorFn) {}
|
constructor(public validator: ValidatorFn, public asyncValidator: AsyncValidatorFn) {}
|
||||||
|
@ -112,10 +113,10 @@ export abstract class AbstractControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; }
|
setParent(parent: ControlGroup|ControlArray): void { this._parent = parent; }
|
||||||
|
|
||||||
updateValueAndValidity(
|
updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
|
||||||
{onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
|
void {
|
||||||
onlySelf = normalizeBool(onlySelf);
|
onlySelf = normalizeBool(onlySelf);
|
||||||
emitEvent = isPresent(emitEvent) ? emitEvent : true;
|
emitEvent = isPresent(emitEvent) ? emitEvent : true;
|
||||||
|
|
||||||
|
@ -196,7 +197,7 @@ export abstract class AbstractControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
find(path: Array<string | number>| string): AbstractControl { return _find(this, path); }
|
find(path: Array<string|number>|string): AbstractControl { return _find(this, path); }
|
||||||
|
|
||||||
getError(errorCode: string, path: string[] = null): any {
|
getError(errorCode: string, path: string[] = null): any {
|
||||||
var control = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this;
|
var control = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this;
|
||||||
|
@ -273,8 +274,8 @@ export class Control extends AbstractControl {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_onChange: Function;
|
_onChange: Function;
|
||||||
|
|
||||||
constructor(value: any = null, validator: ValidatorFn = null,
|
constructor(
|
||||||
asyncValidator: AsyncValidatorFn = null) {
|
value: any = null, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._value = value;
|
this._value = value;
|
||||||
this.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
this.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
||||||
|
@ -339,9 +340,9 @@ export class Control extends AbstractControl {
|
||||||
export class ControlGroup extends AbstractControl {
|
export class ControlGroup extends AbstractControl {
|
||||||
private _optionals: {[key: string]: boolean};
|
private _optionals: {[key: string]: boolean};
|
||||||
|
|
||||||
constructor(public controls: {[key: string]: AbstractControl},
|
constructor(
|
||||||
optionals: {[key: string]: boolean} = null, validator: ValidatorFn = null,
|
public controls: {[key: string]: AbstractControl}, optionals: {[key: string]: boolean} = null,
|
||||||
asyncValidator: AsyncValidatorFn = null) {
|
validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._optionals = isPresent(optionals) ? optionals : {};
|
this._optionals = isPresent(optionals) ? optionals : {};
|
||||||
this._initObservables();
|
this._initObservables();
|
||||||
|
@ -467,8 +468,9 @@ export class ControlGroup extends AbstractControl {
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export class ControlArray extends AbstractControl {
|
export class ControlArray extends AbstractControl {
|
||||||
constructor(public controls: AbstractControl[], validator: ValidatorFn = null,
|
constructor(
|
||||||
asyncValidator: AsyncValidatorFn = null) {
|
public controls: AbstractControl[], validator: ValidatorFn = null,
|
||||||
|
asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._initObservables();
|
this._initObservables();
|
||||||
this._setParentForControls();
|
this._setParentForControls();
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import {OpaqueToken} from '@angular/core';
|
import {OpaqueToken} from '@angular/core';
|
||||||
import {isBlank, isPresent, isString} from '../facade/lang';
|
|
||||||
import {PromiseWrapper} from '../facade/promise';
|
|
||||||
import {ObservableWrapper} from '../facade/async';
|
import {ObservableWrapper} from '../facade/async';
|
||||||
import {StringMapWrapper} from '../facade/collection';
|
import {StringMapWrapper} from '../facade/collection';
|
||||||
|
import {isBlank, isPresent, isString} from '../facade/lang';
|
||||||
|
import {PromiseWrapper} from '../facade/promise';
|
||||||
|
|
||||||
|
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
|
||||||
import * as modelModule from './model';
|
import * as modelModule from './model';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Providers for validators to be used for {@link Control}s in a form.
|
* Providers for validators to be used for {@link Control}s in a form.
|
||||||
|
@ -16,7 +19,7 @@ import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
||||||
* {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'}
|
* {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'}
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const NG_VALIDATORS: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken("NgValidators");
|
export const NG_VALIDATORS: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken('NgValidators');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Providers for asynchronous validators to be used for {@link Control}s
|
* Providers for asynchronous validators to be used for {@link Control}s
|
||||||
|
@ -29,7 +32,7 @@ export const NG_VALIDATORS: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken("Ng
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const NG_ASYNC_VALIDATORS: OpaqueToken =
|
export const NG_ASYNC_VALIDATORS: OpaqueToken =
|
||||||
/*@ts2dart_const*/ new OpaqueToken("NgAsyncValidators");
|
/*@ts2dart_const*/ new OpaqueToken('NgAsyncValidators');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a set of validators used by form controls.
|
* Provides a set of validators used by form controls.
|
||||||
|
@ -50,9 +53,9 @@ export class Validators {
|
||||||
* Validator that requires controls to have a non-empty value.
|
* Validator that requires controls to have a non-empty value.
|
||||||
*/
|
*/
|
||||||
static required(control: modelModule.AbstractControl): {[key: string]: boolean} {
|
static required(control: modelModule.AbstractControl): {[key: string]: boolean} {
|
||||||
return isBlank(control.value) || (isString(control.value) && control.value == "") ?
|
return isBlank(control.value) || (isString(control.value) && control.value == '') ?
|
||||||
{"required": true} :
|
{'required': true} :
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,8 +66,8 @@ export class Validators {
|
||||||
if (isPresent(Validators.required(control))) return null;
|
if (isPresent(Validators.required(control))) return null;
|
||||||
var v: string = control.value;
|
var v: string = control.value;
|
||||||
return v.length < minLength ?
|
return v.length < minLength ?
|
||||||
{"minlength": {"requiredLength": minLength, "actualLength": v.length}} :
|
{'minlength': {'requiredLength': minLength, 'actualLength': v.length}} :
|
||||||
null;
|
null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +79,8 @@ export class Validators {
|
||||||
if (isPresent(Validators.required(control))) return null;
|
if (isPresent(Validators.required(control))) return null;
|
||||||
var v: string = control.value;
|
var v: string = control.value;
|
||||||
return v.length > maxLength ?
|
return v.length > maxLength ?
|
||||||
{"maxlength": {"requiredLength": maxLength, "actualLength": v.length}} :
|
{'maxlength': {'requiredLength': maxLength, 'actualLength': v.length}} :
|
||||||
null;
|
null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +93,7 @@ export class Validators {
|
||||||
let regex = new RegExp(`^${pattern}$`);
|
let regex = new RegExp(`^${pattern}$`);
|
||||||
let v: string = control.value;
|
let v: string = control.value;
|
||||||
return regex.test(v) ? null :
|
return regex.test(v) ? null :
|
||||||
{"pattern": {"requiredPattern": `^${pattern}$`, "actualValue": v}};
|
{'pattern': {'requiredPattern': `^${pattern}$`, 'actualValue': v}};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,13 +132,13 @@ function _convertToPromise(obj: any): any {
|
||||||
return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj);
|
return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _executeValidators(control: modelModule.AbstractControl,
|
function _executeValidators(
|
||||||
validators: ValidatorFn[]): any[] {
|
control: modelModule.AbstractControl, validators: ValidatorFn[]): any[] {
|
||||||
return validators.map(v => v(control));
|
return validators.map(v => v(control));
|
||||||
}
|
}
|
||||||
|
|
||||||
function _executeAsyncValidators(control: modelModule.AbstractControl,
|
function _executeAsyncValidators(
|
||||||
validators: AsyncValidatorFn[]): any[] {
|
control: modelModule.AbstractControl, validators: AsyncValidatorFn[]): any[] {
|
||||||
return validators.map(v => v(control));
|
return validators.map(v => v(control));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import {Injectable, Inject, Optional} from '@angular/core';
|
import {Inject, Injectable, Optional} from '@angular/core';
|
||||||
|
|
||||||
import {isPresent} from '../facade/lang';
|
import {isPresent} from '../facade/lang';
|
||||||
|
|
||||||
import {LocationStrategy, APP_BASE_HREF} from './location_strategy';
|
|
||||||
import {Location} from './location';
|
import {Location} from './location';
|
||||||
import {UrlChangeListener, PlatformLocation} from './platform_location';
|
import {APP_BASE_HREF, LocationStrategy} from './location_strategy';
|
||||||
|
import {PlatformLocation, UrlChangeListener} from './platform_location';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,8 +53,9 @@ import {UrlChangeListener, PlatformLocation} from './platform_location';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class HashLocationStrategy extends LocationStrategy {
|
export class HashLocationStrategy extends LocationStrategy {
|
||||||
private _baseHref: string = '';
|
private _baseHref: string = '';
|
||||||
constructor(private _platformLocation: PlatformLocation,
|
constructor(
|
||||||
@Optional() @Inject(APP_BASE_HREF) _baseHref?: string) {
|
private _platformLocation: PlatformLocation,
|
||||||
|
@Optional() @Inject(APP_BASE_HREF) _baseHref?: string) {
|
||||||
super();
|
super();
|
||||||
if (isPresent(_baseHref)) {
|
if (isPresent(_baseHref)) {
|
||||||
this._baseHref = _baseHref;
|
this._baseHref = _baseHref;
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import {Injectable, EventEmitter} from '@angular/core';
|
import {EventEmitter, Injectable} from '@angular/core';
|
||||||
|
|
||||||
import {ObservableWrapper} from '../facade/async';
|
import {ObservableWrapper} from '../facade/async';
|
||||||
|
|
||||||
import {LocationStrategy} from './location_strategy';
|
import {LocationStrategy} from './location_strategy';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `Location` is a service that applications can use to interact with a browser's URL.
|
* `Location` is a service that applications can use to interact with a browser's URL.
|
||||||
* Depending on which {@link LocationStrategy} is used, `Location` will either persist
|
* Depending on which {@link LocationStrategy} is used, `Location` will either persist
|
||||||
|
@ -127,8 +129,9 @@ export class Location {
|
||||||
/**
|
/**
|
||||||
* Subscribe to the platform's `popState` events.
|
* Subscribe to the platform's `popState` events.
|
||||||
*/
|
*/
|
||||||
subscribe(onNext: (value: any) => void, onThrow: (exception: any) => void = null,
|
subscribe(
|
||||||
onReturn: () => void = null): Object {
|
onNext: (value: any) => void, onThrow: (exception: any) => void = null,
|
||||||
|
onReturn: () => void = null): Object {
|
||||||
return ObservableWrapper.subscribe(this._subject, onNext, onThrow, onReturn);
|
return ObservableWrapper.subscribe(this._subject, onNext, onThrow, onReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import {Injectable, Inject, Optional} from '@angular/core';
|
import {Inject, Injectable, Optional} from '@angular/core';
|
||||||
import {isBlank} from '../facade/lang';
|
|
||||||
import {BaseException} from '../facade/exceptions';
|
import {BaseException} from '../facade/exceptions';
|
||||||
|
import {isBlank} from '../facade/lang';
|
||||||
|
|
||||||
import {PlatformLocation, UrlChangeListener} from './platform_location';
|
|
||||||
import {LocationStrategy, APP_BASE_HREF} from './location_strategy';
|
|
||||||
import {Location} from './location';
|
import {Location} from './location';
|
||||||
|
import {APP_BASE_HREF, LocationStrategy} from './location_strategy';
|
||||||
|
import {PlatformLocation, UrlChangeListener} from './platform_location';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `PathLocationStrategy` is a {@link LocationStrategy} used to configure the
|
* `PathLocationStrategy` is a {@link LocationStrategy} used to configure the
|
||||||
|
@ -60,8 +62,9 @@ import {Location} from './location';
|
||||||
export class PathLocationStrategy extends LocationStrategy {
|
export class PathLocationStrategy extends LocationStrategy {
|
||||||
private _baseHref: string;
|
private _baseHref: string;
|
||||||
|
|
||||||
constructor(private _platformLocation: PlatformLocation,
|
constructor(
|
||||||
@Optional() @Inject(APP_BASE_HREF) href?: string) {
|
private _platformLocation: PlatformLocation,
|
||||||
|
@Optional() @Inject(APP_BASE_HREF) href?: string) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if (isBlank(href)) {
|
if (isBlank(href)) {
|
||||||
|
@ -89,7 +92,7 @@ export class PathLocationStrategy extends LocationStrategy {
|
||||||
|
|
||||||
path(): string {
|
path(): string {
|
||||||
return this._platformLocation.pathname +
|
return this._platformLocation.pathname +
|
||||||
Location.normalizeQueryParams(this._platformLocation.search);
|
Location.normalizeQueryParams(this._platformLocation.search);
|
||||||
}
|
}
|
||||||
|
|
||||||
pushState(state: any, title: string, url: string, queryParams: string) {
|
pushState(state: any, title: string, url: string, queryParams: string) {
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export {AsyncPipe} from './pipes/async_pipe';
|
export {AsyncPipe} from './pipes/async_pipe';
|
||||||
|
export {COMMON_PIPES} from './pipes/common_pipes';
|
||||||
export {DatePipe} from './pipes/date_pipe';
|
export {DatePipe} from './pipes/date_pipe';
|
||||||
export {JsonPipe} from './pipes/json_pipe';
|
|
||||||
export {SlicePipe} from './pipes/slice_pipe';
|
|
||||||
export {LowerCasePipe} from './pipes/lowercase_pipe';
|
|
||||||
export {DecimalPipe, PercentPipe, CurrencyPipe} from './pipes/number_pipe';
|
|
||||||
export {UpperCasePipe} from './pipes/uppercase_pipe';
|
|
||||||
export {ReplacePipe} from './pipes/replace_pipe';
|
|
||||||
export {I18nPluralPipe} from './pipes/i18n_plural_pipe';
|
export {I18nPluralPipe} from './pipes/i18n_plural_pipe';
|
||||||
export {I18nSelectPipe} from './pipes/i18n_select_pipe';
|
export {I18nSelectPipe} from './pipes/i18n_select_pipe';
|
||||||
export {COMMON_PIPES} from './pipes/common_pipes';
|
export {JsonPipe} from './pipes/json_pipe';
|
||||||
|
export {LowerCasePipe} from './pipes/lowercase_pipe';
|
||||||
|
export {CurrencyPipe, DecimalPipe, PercentPipe} from './pipes/number_pipe';
|
||||||
|
export {ReplacePipe} from './pipes/replace_pipe';
|
||||||
|
export {SlicePipe} from './pipes/slice_pipe';
|
||||||
|
export {UpperCasePipe} from './pipes/uppercase_pipe';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {Pipe, Injectable, ChangeDetectorRef, OnDestroy, WrappedValue} from '@angular/core';
|
import {ChangeDetectorRef, Injectable, OnDestroy, Pipe, WrappedValue} from '@angular/core';
|
||||||
|
|
||||||
|
import {EventEmitter, Observable, ObservableWrapper} from '../facade/async';
|
||||||
import {isBlank, isPresent, isPromise} from '../facade/lang';
|
import {isBlank, isPresent, isPromise} from '../facade/lang';
|
||||||
import {ObservableWrapper, Observable, EventEmitter} from '../facade/async';
|
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ interface SubscriptionStrategy {
|
||||||
|
|
||||||
class ObservableStrategy implements SubscriptionStrategy {
|
class ObservableStrategy implements SubscriptionStrategy {
|
||||||
createSubscription(async: any, updateLatestValue: any): any {
|
createSubscription(async: any, updateLatestValue: any): any {
|
||||||
return ObservableWrapper.subscribe(async, updateLatestValue, e => { throw e; } );
|
return ObservableWrapper.subscribe(async, updateLatestValue, e => { throw e; });
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(subscription: any): void { ObservableWrapper.dispose(subscription); }
|
dispose(subscription: any): void { ObservableWrapper.dispose(subscription); }
|
||||||
|
@ -73,7 +73,7 @@ export class AsyncPipe implements OnDestroy {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_subscription: Object = null;
|
_subscription: Object = null;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_obj: Observable<any>| Promise<any>| EventEmitter<any> = null;
|
_obj: Observable<any>|Promise<any>|EventEmitter<any> = null;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_ref: ChangeDetectorRef;
|
_ref: ChangeDetectorRef;
|
||||||
private _strategy: SubscriptionStrategy = null;
|
private _strategy: SubscriptionStrategy = null;
|
||||||
|
@ -86,7 +86,7 @@ export class AsyncPipe implements OnDestroy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transform(obj: Observable<any>| Promise<any>| EventEmitter<any>): any {
|
transform(obj: Observable<any>|Promise<any>|EventEmitter<any>): any {
|
||||||
if (isBlank(this._obj)) {
|
if (isBlank(this._obj)) {
|
||||||
if (isPresent(obj)) {
|
if (isPresent(obj)) {
|
||||||
this._subscribe(obj);
|
this._subscribe(obj);
|
||||||
|
@ -109,7 +109,7 @@ export class AsyncPipe implements OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_subscribe(obj: Observable<any>| Promise<any>| EventEmitter<any>): void {
|
_subscribe(obj: Observable<any>|Promise<any>|EventEmitter<any>): void {
|
||||||
this._obj = obj;
|
this._obj = obj;
|
||||||
this._strategy = this._selectStrategy(obj);
|
this._strategy = this._selectStrategy(obj);
|
||||||
this._subscription = this._strategy.createSubscription(
|
this._subscription = this._strategy.createSubscription(
|
||||||
|
@ -117,7 +117,7 @@ export class AsyncPipe implements OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_selectStrategy(obj: Observable<any>| Promise<any>| EventEmitter<any>): any {
|
_selectStrategy(obj: Observable<any>|Promise<any>|EventEmitter<any>): any {
|
||||||
if (isPromise(obj)) {
|
if (isPromise(obj)) {
|
||||||
return _promiseStrategy;
|
return _promiseStrategy;
|
||||||
} else if (ObservableWrapper.isObservable(obj)) {
|
} else if (ObservableWrapper.isObservable(obj)) {
|
||||||
|
|
|
@ -4,15 +4,16 @@
|
||||||
* This module provides a set of common Pipes.
|
* This module provides a set of common Pipes.
|
||||||
*/
|
*/
|
||||||
import {AsyncPipe} from './async_pipe';
|
import {AsyncPipe} from './async_pipe';
|
||||||
import {UpperCasePipe} from './uppercase_pipe';
|
|
||||||
import {LowerCasePipe} from './lowercase_pipe';
|
|
||||||
import {JsonPipe} from './json_pipe';
|
|
||||||
import {SlicePipe} from './slice_pipe';
|
|
||||||
import {DatePipe} from './date_pipe';
|
import {DatePipe} from './date_pipe';
|
||||||
import {DecimalPipe, PercentPipe, CurrencyPipe} from './number_pipe';
|
|
||||||
import {ReplacePipe} from './replace_pipe';
|
|
||||||
import {I18nPluralPipe} from './i18n_plural_pipe';
|
import {I18nPluralPipe} from './i18n_plural_pipe';
|
||||||
import {I18nSelectPipe} from './i18n_select_pipe';
|
import {I18nSelectPipe} from './i18n_select_pipe';
|
||||||
|
import {JsonPipe} from './json_pipe';
|
||||||
|
import {LowerCasePipe} from './lowercase_pipe';
|
||||||
|
import {CurrencyPipe, DecimalPipe, PercentPipe} from './number_pipe';
|
||||||
|
import {ReplacePipe} from './replace_pipe';
|
||||||
|
import {SlicePipe} from './slice_pipe';
|
||||||
|
import {UpperCasePipe} from './uppercase_pipe';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of Angular core pipes that are likely to be used in each and every
|
* A collection of Angular core pipes that are likely to be used in each and every
|
||||||
|
@ -35,5 +36,5 @@ export const COMMON_PIPES = /*@ts2dart_const*/[
|
||||||
DatePipe,
|
DatePipe,
|
||||||
ReplacePipe,
|
ReplacePipe,
|
||||||
I18nPluralPipe,
|
I18nPluralPipe,
|
||||||
I18nSelectPipe
|
I18nSelectPipe,
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
import {PipeTransform, Pipe, Injectable} from '@angular/core';
|
import {Injectable, Pipe, PipeTransform} from '@angular/core';
|
||||||
import {
|
|
||||||
isDate,
|
import {isDate, isNumber, isString, DateWrapper, isBlank,} from '../facade/lang';
|
||||||
isNumber,
|
|
||||||
isString,
|
|
||||||
DateWrapper,
|
|
||||||
isBlank,
|
|
||||||
} from '../facade/lang';
|
|
||||||
import {DateFormatter} from '../facade/intl';
|
import {DateFormatter} from '../facade/intl';
|
||||||
import {StringMapWrapper} from '../facade/collection';
|
import {StringMapWrapper} from '../facade/collection';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import {PipeTransform, Pipe} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {isStringMap, StringWrapper, isPresent, RegExpWrapper} from '../facade/lang';
|
|
||||||
|
import {RegExpWrapper, StringWrapper, isPresent, isStringMap} from '../facade/lang';
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
var interpolationExp: RegExp = RegExpWrapper.create('#');
|
var interpolationExp: RegExp = RegExpWrapper.create('#');
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import {PipeTransform, Pipe} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {isStringMap} from '../facade/lang';
|
|
||||||
import {StringMapWrapper} from '../facade/collection';
|
import {StringMapWrapper} from '../facade/collection';
|
||||||
|
import {isStringMap} from '../facade/lang';
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Generic selector that displays the string that matches the current value.
|
* Generic selector that displays the string that matches the current value.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {Type, stringify} from '../facade/lang';
|
|
||||||
import {BaseException} from '../facade/exceptions';
|
import {BaseException} from '../facade/exceptions';
|
||||||
|
import {Type, stringify} from '../facade/lang';
|
||||||
|
|
||||||
export class InvalidPipeArgumentException extends BaseException {
|
export class InvalidPipeArgumentException extends BaseException {
|
||||||
constructor(type: Type, value: Object) {
|
constructor(type: Type, value: Object) {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import {PipeTransform, Pipe} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
|
|
||||||
import {Json} from '../facade/lang';
|
import {Json} from '../facade/lang';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms any input value using `JSON.stringify`. Useful for debugging.
|
* Transforms any input value using `JSON.stringify`. Useful for debugging.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import {PipeTransform, Pipe} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {isString, isBlank} from '../facade/lang';
|
|
||||||
|
import {isBlank, isString} from '../facade/lang';
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms text to lowercase.
|
* Transforms text to lowercase.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,15 +1,8 @@
|
||||||
import {PipeTransform, Pipe} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
|
|
||||||
import {
|
|
||||||
isNumber,
|
|
||||||
isPresent,
|
|
||||||
isBlank,
|
|
||||||
NumberWrapper,
|
|
||||||
RegExpWrapper,
|
|
||||||
Type
|
|
||||||
} from '../facade/lang';
|
|
||||||
import {BaseException} from '../facade/exceptions';
|
import {BaseException} from '../facade/exceptions';
|
||||||
import {NumberFormatter, NumberFormatStyle} from '../facade/intl';
|
import {NumberFormatStyle, NumberFormatter} from '../facade/intl';
|
||||||
|
import {NumberWrapper, RegExpWrapper, Type, isBlank, isNumber, isPresent} from '../facade/lang';
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
@ -19,8 +12,9 @@ var _re = RegExpWrapper.create('^(\\d+)?\\.((\\d+)(\\-(\\d+))?)?$');
|
||||||
/**
|
/**
|
||||||
* Internal function to format numbers used by Decimal, Percent and Date pipes.
|
* Internal function to format numbers used by Decimal, Percent and Date pipes.
|
||||||
*/
|
*/
|
||||||
function formatNumber(pipe: Type, value: number, style: NumberFormatStyle, digits: string, currency: string = null,
|
function formatNumber(
|
||||||
currencyAsSymbol: boolean = false): string {
|
pipe: Type, value: number, style: NumberFormatStyle, digits: string, currency: string = null,
|
||||||
|
currencyAsSymbol: boolean = false): string {
|
||||||
if (isBlank(value)) return null;
|
if (isBlank(value)) return null;
|
||||||
if (!isNumber(value)) {
|
if (!isNumber(value)) {
|
||||||
throw new InvalidPipeArgumentException(pipe, value);
|
throw new InvalidPipeArgumentException(pipe, value);
|
||||||
|
@ -138,9 +132,10 @@ export class PercentPipe implements PipeTransform {
|
||||||
*/
|
*/
|
||||||
@Pipe({name: 'currency'})
|
@Pipe({name: 'currency'})
|
||||||
export class CurrencyPipe implements PipeTransform {
|
export class CurrencyPipe implements PipeTransform {
|
||||||
transform(value: any, currencyCode: string = 'USD', symbolDisplay: boolean = false,
|
transform(
|
||||||
digits: string = null): string {
|
value: any, currencyCode: string = 'USD', symbolDisplay: boolean = false,
|
||||||
return formatNumber(CurrencyPipe, value, NumberFormatStyle.Currency, digits, currencyCode,
|
digits: string = null): string {
|
||||||
symbolDisplay);
|
return formatNumber(
|
||||||
|
CurrencyPipe, value, NumberFormatStyle.Currency, digits, currencyCode, symbolDisplay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
import {Injectable, PipeTransform, Pipe} from '@angular/core';
|
import {Injectable, Pipe, PipeTransform} from '@angular/core';
|
||||||
|
|
||||||
import {
|
import {RegExpWrapper, StringWrapper, isBlank, isFunction, isNumber, isString} from '../facade/lang';
|
||||||
isBlank,
|
|
||||||
isString,
|
|
||||||
isNumber,
|
|
||||||
isFunction,
|
|
||||||
RegExpWrapper,
|
|
||||||
StringWrapper
|
|
||||||
} from '../facade/lang';
|
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
@ -44,7 +37,7 @@ import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
@Pipe({name: 'replace'})
|
@Pipe({name: 'replace'})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ReplacePipe implements PipeTransform {
|
export class ReplacePipe implements PipeTransform {
|
||||||
transform(value: any, pattern: string | RegExp, replacement: Function | string): any {
|
transform(value: any, pattern: string|RegExp, replacement: Function|string): any {
|
||||||
if (isBlank(value)) {
|
if (isBlank(value)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {PipeTransform, Pipe} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {isBlank, isString, isArray, StringWrapper} from '../facade/lang';
|
|
||||||
import {ListWrapper} from '../facade/collection';
|
import {ListWrapper} from '../facade/collection';
|
||||||
|
import {StringWrapper, isArray, isBlank, isString} from '../facade/lang';
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import {PipeTransform, Pipe} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {isString, isBlank} from '../facade/lang';
|
|
||||||
|
import {isBlank, isString} from '../facade/lang';
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements uppercase transforms to text.
|
* Implements uppercase transforms to text.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,15 +1,4 @@
|
||||||
import {
|
import {beforeEach, beforeEachProviders, ddescribe, xdescribe, describe, expect, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
beforeEach,
|
|
||||||
beforeEachProviders,
|
|
||||||
ddescribe,
|
|
||||||
xdescribe,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
iit,
|
|
||||||
inject,
|
|
||||||
it,
|
|
||||||
xit,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {ComponentFixture, TestComponentBuilder} from '@angular/compiler/testing';
|
import {ComponentFixture, TestComponentBuilder} from '@angular/compiler/testing';
|
||||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
import {ListWrapper, StringMapWrapper, SetWrapper} from '../../src/facade/collection';
|
import {ListWrapper, StringMapWrapper, SetWrapper} from '../../src/facade/collection';
|
||||||
|
@ -25,499 +14,564 @@ export function main() {
|
||||||
describe('binding to CSS class list', () => {
|
describe('binding to CSS class list', () => {
|
||||||
|
|
||||||
it('should clean up when the directive is destroyed',
|
it('should clean up when the directive is destroyed',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div *ngFor="let item of items" [ngClass]="item"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.createAsync(TestComponent)
|
var template = '<div *ngFor="let item of items" [ngClass]="item"></div>';
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
fixture.debugElement.componentInstance.items = [['0']];
|
.createAsync(TestComponent)
|
||||||
fixture.detectChanges();
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = [['1']];
|
fixture.debugElement.componentInstance.items = [['0']];
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.debugElement.componentInstance.items = [['1']];
|
||||||
|
|
||||||
detectChangesAndCheck(fixture, '1');
|
detectChangesAndCheck(fixture, '1');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
describe('expressions evaluating to objects', () => {
|
describe('expressions evaluating to objects', () => {
|
||||||
|
|
||||||
it('should add classes specified in an object literal',
|
it('should add classes specified in an object literal',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="{foo: true, bar: false}"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="{foo: true, bar: false}"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should add classes specified in an object literal without change in class names',
|
it('should add classes specified in an object literal without change in class names',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngClass]="{'foo-bar': true, 'fooBar': true}"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngClass]="{'foo-bar': true, 'fooBar': true}"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo-bar fooBar');
|
detectChangesAndCheck(fixture, 'foo-bar fooBar');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should add and remove classes based on changes in object literal values',
|
it('should add and remove classes based on changes in object literal values',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="{foo: condition, bar: !condition}"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="{foo: condition, bar: !condition}"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.condition = false;
|
fixture.debugElement.componentInstance.condition = false;
|
||||||
detectChangesAndCheck(fixture, 'bar');
|
detectChangesAndCheck(fixture, 'bar');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should add and remove classes based on changes to the expression object',
|
it('should add and remove classes based on changes to the expression object',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="objExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="objExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, 'foo bar');
|
fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
||||||
|
detectChangesAndCheck(fixture, 'foo bar');
|
||||||
|
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'baz', true);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, 'foo bar baz');
|
fixture.debugElement.componentInstance.objExpr, 'baz', true);
|
||||||
|
detectChangesAndCheck(fixture, 'foo bar baz');
|
||||||
|
|
||||||
StringMapWrapper.delete(fixture.debugElement.componentInstance.objExpr, 'bar');
|
StringMapWrapper.delete(fixture.debugElement.componentInstance.objExpr, 'bar');
|
||||||
detectChangesAndCheck(fixture, 'foo baz');
|
detectChangesAndCheck(fixture, 'foo baz');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should add and remove classes based on reference changes to the expression object',
|
it('should add and remove classes based on reference changes to the expression object',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="objExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="objExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = {foo: true, bar: true};
|
fixture.debugElement.componentInstance.objExpr = {foo: true, bar: true};
|
||||||
detectChangesAndCheck(fixture, 'foo bar');
|
detectChangesAndCheck(fixture, 'foo bar');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = {baz: true};
|
fixture.debugElement.componentInstance.objExpr = {baz: true};
|
||||||
detectChangesAndCheck(fixture, 'baz');
|
detectChangesAndCheck(fixture, 'baz');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should remove active classes when expression evaluates to null',
|
it('should remove active classes when expression evaluates to null',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="objExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="objExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = null;
|
fixture.debugElement.componentInstance.objExpr = null;
|
||||||
detectChangesAndCheck(fixture, '');
|
detectChangesAndCheck(fixture, '');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = {'foo': false, 'bar': true};
|
fixture.debugElement.componentInstance.objExpr = {'foo': false, 'bar': true};
|
||||||
detectChangesAndCheck(fixture, 'bar');
|
detectChangesAndCheck(fixture, 'bar');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should allow multiple classes per expression',
|
it('should allow multiple classes per expression',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="objExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="objExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = {
|
fixture.debugElement.componentInstance.objExpr = {
|
||||||
'bar baz': true,
|
'bar baz': true,
|
||||||
'bar1 baz1': true
|
'bar1 baz1': true
|
||||||
};
|
};
|
||||||
detectChangesAndCheck(fixture, 'bar baz bar1 baz1');
|
detectChangesAndCheck(fixture, 'bar baz bar1 baz1');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = {
|
fixture.debugElement.componentInstance.objExpr = {
|
||||||
'bar baz': false,
|
'bar baz': false,
|
||||||
'bar1 baz1': true
|
'bar1 baz1': true
|
||||||
};
|
};
|
||||||
detectChangesAndCheck(fixture, 'bar1 baz1');
|
detectChangesAndCheck(fixture, 'bar1 baz1');
|
||||||
|
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should split by one or more spaces between classes',
|
it('should split by one or more spaces between classes',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="objExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="objExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = {'foo bar baz': true};
|
fixture.debugElement.componentInstance.objExpr = {'foo bar baz': true};
|
||||||
detectChangesAndCheck(fixture, 'foo bar baz');
|
detectChangesAndCheck(fixture, 'foo bar baz');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('expressions evaluating to lists', () => {
|
describe('expressions evaluating to lists', () => {
|
||||||
|
|
||||||
it('should add classes specified in a list literal',
|
it('should add classes specified in a list literal',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngClass]="['foo', 'bar', 'foo-bar', 'fooBar']"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngClass]="['foo', 'bar', 'foo-bar', 'fooBar']"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo bar foo-bar fooBar');
|
detectChangesAndCheck(fixture, 'foo bar foo-bar fooBar');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should add and remove classes based on changes to the expression',
|
it('should add and remove classes based on changes to the expression',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="arrExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="arrExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var arrExpr: string[] = fixture.debugElement.componentInstance.arrExpr;
|
var arrExpr: string[] = fixture.debugElement.componentInstance.arrExpr;
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
arrExpr.push('bar');
|
arrExpr.push('bar');
|
||||||
detectChangesAndCheck(fixture, 'foo bar');
|
detectChangesAndCheck(fixture, 'foo bar');
|
||||||
|
|
||||||
arrExpr[1] = 'baz';
|
arrExpr[1] = 'baz';
|
||||||
detectChangesAndCheck(fixture, 'foo baz');
|
detectChangesAndCheck(fixture, 'foo baz');
|
||||||
|
|
||||||
ListWrapper.remove(fixture.debugElement.componentInstance.arrExpr, 'baz');
|
ListWrapper.remove(fixture.debugElement.componentInstance.arrExpr, 'baz');
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should add and remove classes when a reference changes',
|
it('should add and remove classes when a reference changes',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="arrExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="arrExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.arrExpr = ['bar'];
|
fixture.debugElement.componentInstance.arrExpr = ['bar'];
|
||||||
detectChangesAndCheck(fixture, 'bar');
|
detectChangesAndCheck(fixture, 'bar');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should take initial classes into account when a reference changes',
|
it('should take initial classes into account when a reference changes',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div class="foo" [ngClass]="arrExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div class="foo" [ngClass]="arrExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.arrExpr = ['bar'];
|
fixture.debugElement.componentInstance.arrExpr = ['bar'];
|
||||||
detectChangesAndCheck(fixture, 'foo bar');
|
detectChangesAndCheck(fixture, 'foo bar');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should ignore empty or blank class names',
|
it('should ignore empty or blank class names',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div class="foo" [ngClass]="arrExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div class="foo" [ngClass]="arrExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.arrExpr = ['', ' '];
|
fixture.debugElement.componentInstance.arrExpr = ['', ' '];
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should trim blanks from class names',
|
it('should trim blanks from class names',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div class="foo" [ngClass]="arrExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div class="foo" [ngClass]="arrExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.arrExpr = [' bar '];
|
fixture.debugElement.componentInstance.arrExpr = [' bar '];
|
||||||
detectChangesAndCheck(fixture, 'foo bar');
|
detectChangesAndCheck(fixture, 'foo bar');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should allow multiple classes per item in arrays',
|
it('should allow multiple classes per item in arrays',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="arrExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="arrExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.arrExpr =
|
fixture.debugElement.componentInstance.arrExpr =
|
||||||
['foo bar baz', 'foo1 bar1 baz1'];
|
['foo bar baz', 'foo1 bar1 baz1'];
|
||||||
detectChangesAndCheck(fixture, 'foo bar baz foo1 bar1 baz1');
|
detectChangesAndCheck(fixture, 'foo bar baz foo1 bar1 baz1');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.arrExpr = ['foo bar baz foobar'];
|
fixture.debugElement.componentInstance.arrExpr = ['foo bar baz foobar'];
|
||||||
detectChangesAndCheck(fixture, 'foo bar baz foobar');
|
detectChangesAndCheck(fixture, 'foo bar baz foobar');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('expressions evaluating to sets', () => {
|
describe('expressions evaluating to sets', () => {
|
||||||
|
|
||||||
it('should add and remove classes if the set instance changed',
|
it('should add and remove classes if the set instance changed',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="setExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="setExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var setExpr = new Set<string>();
|
var setExpr = new Set<string>();
|
||||||
setExpr.add('bar');
|
setExpr.add('bar');
|
||||||
fixture.debugElement.componentInstance.setExpr = setExpr;
|
fixture.debugElement.componentInstance.setExpr = setExpr;
|
||||||
detectChangesAndCheck(fixture, 'bar');
|
detectChangesAndCheck(fixture, 'bar');
|
||||||
|
|
||||||
setExpr = new Set<string>();
|
setExpr = new Set<string>();
|
||||||
setExpr.add('baz');
|
setExpr.add('baz');
|
||||||
fixture.debugElement.componentInstance.setExpr = setExpr;
|
fixture.debugElement.componentInstance.setExpr = setExpr;
|
||||||
detectChangesAndCheck(fixture, 'baz');
|
detectChangesAndCheck(fixture, 'baz');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
describe('expressions evaluating to string', () => {
|
describe('expressions evaluating to string', () => {
|
||||||
|
|
||||||
it('should add classes specified in a string literal',
|
it('should add classes specified in a string literal',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngClass]="'foo bar foo-bar fooBar'"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngClass]="'foo bar foo-bar fooBar'"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo bar foo-bar fooBar');
|
detectChangesAndCheck(fixture, 'foo bar foo-bar fooBar');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should add and remove classes based on changes to the expression',
|
it('should add and remove classes based on changes to the expression',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="strExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="strExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.strExpr = 'foo bar';
|
fixture.debugElement.componentInstance.strExpr = 'foo bar';
|
||||||
detectChangesAndCheck(fixture, 'foo bar');
|
detectChangesAndCheck(fixture, 'foo bar');
|
||||||
|
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.strExpr = 'baz';
|
fixture.debugElement.componentInstance.strExpr = 'baz';
|
||||||
detectChangesAndCheck(fixture, 'baz');
|
detectChangesAndCheck(fixture, 'baz');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should remove active classes when switching from string to null',
|
it('should remove active classes when switching from string to null',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngClass]="strExpr"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngClass]="strExpr"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.strExpr = null;
|
fixture.debugElement.componentInstance.strExpr = null;
|
||||||
detectChangesAndCheck(fixture, '');
|
detectChangesAndCheck(fixture, '');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should take initial classes into account when switching from string to null',
|
it('should take initial classes into account when switching from string to null',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div class="foo" [ngClass]="strExpr"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div class="foo" [ngClass]="strExpr"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.strExpr = null;
|
fixture.debugElement.componentInstance.strExpr = null;
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should ignore empty and blank strings',
|
it('should ignore empty and blank strings',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div class="foo" [ngClass]="strExpr"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div class="foo" [ngClass]="strExpr"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.strExpr = '';
|
fixture.debugElement.componentInstance.strExpr = '';
|
||||||
detectChangesAndCheck(fixture, 'foo');
|
detectChangesAndCheck(fixture, 'foo');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('cooperation with other class-changing constructs', () => {
|
describe('cooperation with other class-changing constructs', () => {
|
||||||
|
|
||||||
it('should co-operate with the class attribute',
|
it('should co-operate with the class attribute',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div [ngClass]="objExpr" class="init foo"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div [ngClass]="objExpr" class="init foo"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, 'init foo bar');
|
fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
||||||
|
detectChangesAndCheck(fixture, 'init foo bar');
|
||||||
|
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'foo', false);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, 'init bar');
|
fixture.debugElement.componentInstance.objExpr, 'foo', false);
|
||||||
|
detectChangesAndCheck(fixture, 'init bar');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = null;
|
fixture.debugElement.componentInstance.objExpr = null;
|
||||||
detectChangesAndCheck(fixture, 'init foo');
|
detectChangesAndCheck(fixture, 'init foo');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should co-operate with the interpolated class attribute',
|
it('should co-operate with the interpolated class attribute',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngClass]="objExpr" class="{{'init foo'}}"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngClass]="objExpr" class="{{'init foo'}}"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, `init foo bar`);
|
fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
||||||
|
detectChangesAndCheck(fixture, `init foo bar`);
|
||||||
|
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'foo', false);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, `init bar`);
|
fixture.debugElement.componentInstance.objExpr, 'foo', false);
|
||||||
|
detectChangesAndCheck(fixture, `init bar`);
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = null;
|
fixture.debugElement.componentInstance.objExpr = null;
|
||||||
detectChangesAndCheck(fixture, `init foo`);
|
detectChangesAndCheck(fixture, `init foo`);
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should co-operate with the class attribute and binding to it',
|
it('should co-operate with the class attribute and binding to it',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngClass]="objExpr" class="init" [class]="'foo'"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngClass]="objExpr" class="init" [class]="'foo'"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, `init foo bar`);
|
fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
||||||
|
detectChangesAndCheck(fixture, `init foo bar`);
|
||||||
|
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'foo', false);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, `init bar`);
|
fixture.debugElement.componentInstance.objExpr, 'foo', false);
|
||||||
|
detectChangesAndCheck(fixture, `init bar`);
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = null;
|
fixture.debugElement.componentInstance.objExpr = null;
|
||||||
detectChangesAndCheck(fixture, `init foo`);
|
detectChangesAndCheck(fixture, `init foo`);
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should co-operate with the class attribute and class.name binding',
|
it('should co-operate with the class attribute and class.name binding',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div class="init foo" [ngClass]="objExpr" [class.baz]="condition"></div>';
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template =
|
||||||
|
'<div class="init foo" [ngClass]="objExpr" [class.baz]="condition"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'init foo baz');
|
detectChangesAndCheck(fixture, 'init foo baz');
|
||||||
|
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, 'init foo baz bar');
|
fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
||||||
|
detectChangesAndCheck(fixture, 'init foo baz bar');
|
||||||
|
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'foo', false);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, 'init baz bar');
|
fixture.debugElement.componentInstance.objExpr, 'foo', false);
|
||||||
|
detectChangesAndCheck(fixture, 'init baz bar');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.condition = false;
|
fixture.debugElement.componentInstance.condition = false;
|
||||||
detectChangesAndCheck(fixture, 'init bar');
|
detectChangesAndCheck(fixture, 'init bar');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should co-operate with initial class and class attribute binding when binding changes',
|
it('should co-operate with initial class and class attribute binding when binding changes',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div class="init" [ngClass]="objExpr" [class]="strExpr"></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = '<div class="init" [ngClass]="objExpr" [class]="strExpr"></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
detectChangesAndCheck(fixture, 'init foo');
|
detectChangesAndCheck(fixture, 'init foo');
|
||||||
|
|
||||||
StringMapWrapper.set(fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
StringMapWrapper.set(
|
||||||
detectChangesAndCheck(fixture, 'init foo bar');
|
fixture.debugElement.componentInstance.objExpr, 'bar', true);
|
||||||
|
detectChangesAndCheck(fixture, 'init foo bar');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.strExpr = 'baz';
|
fixture.debugElement.componentInstance.strExpr = 'baz';
|
||||||
detectChangesAndCheck(fixture, 'init bar baz foo');
|
detectChangesAndCheck(fixture, 'init bar baz foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.objExpr = null;
|
fixture.debugElement.componentInstance.objExpr = null;
|
||||||
detectChangesAndCheck(fixture, 'init baz');
|
detectChangesAndCheck(fixture, 'init baz');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
import {
|
import {beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
beforeEach,
|
|
||||||
beforeEachProviders,
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
iit,
|
|
||||||
inject,
|
|
||||||
it,
|
|
||||||
xit,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {expect} from '@angular/platform-browser/testing';
|
import {expect} from '@angular/platform-browser/testing';
|
||||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
||||||
|
@ -25,482 +16,535 @@ export function main() {
|
||||||
'<div><copy-me template="ngFor let item of items">{{item.toString()}};</copy-me></div>';
|
'<div><copy-me template="ngFor let item of items">{{item.toString()}};</copy-me></div>';
|
||||||
|
|
||||||
it('should reflect initial elements',
|
it('should reflect initial elements',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
|
.then((fixture) => {
|
||||||
async.done();
|
fixture.detectChanges();
|
||||||
});
|
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
|
||||||
}));
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should reflect added elements',
|
it('should reflect added elements',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
(<number[]>fixture.debugElement.componentInstance.items).push(3);
|
(<number[]>fixture.debugElement.componentInstance.items).push(3);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('1;2;3;');
|
expect(fixture.debugElement.nativeElement).toHaveText('1;2;3;');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should reflect removed elements',
|
it('should reflect removed elements',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 1);
|
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 1);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('1;');
|
expect(fixture.debugElement.nativeElement).toHaveText('1;');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should reflect moved elements',
|
it('should reflect moved elements',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 0);
|
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 0);
|
||||||
(<number[]>fixture.debugElement.componentInstance.items).push(1);
|
(<number[]>fixture.debugElement.componentInstance.items).push(1);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('2;1;');
|
expect(fixture.debugElement.nativeElement).toHaveText('2;1;');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should reflect a mix of all changes (additions/removals/moves)',
|
it('should reflect a mix of all changes (additions/removals/moves)',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
fixture.debugElement.componentInstance.items = [0, 1, 2, 3, 4, 5];
|
.createAsync(TestComponent)
|
||||||
fixture.detectChanges();
|
.then((fixture) => {
|
||||||
|
fixture.debugElement.componentInstance.items = [0, 1, 2, 3, 4, 5];
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [6, 2, 7, 0, 4, 8];
|
fixture.debugElement.componentInstance.items = [6, 2, 7, 0, 4, 8];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('6;2;7;0;4;8;');
|
expect(fixture.debugElement.nativeElement).toHaveText('6;2;7;0;4;8;');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should iterate over an array of objects',
|
it('should iterate over an array of objects',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<ul><li template="ngFor let item of items">{{item["name"]}};</li></ul>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template =
|
||||||
|
'<ul><li template="ngFor let item of items">{{item["name"]}};</li></ul>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
|
|
||||||
// INIT
|
// INIT
|
||||||
fixture.debugElement.componentInstance.items =
|
fixture.debugElement.componentInstance.items =
|
||||||
[{'name': 'misko'}, {'name': 'shyam'}];
|
[{'name': 'misko'}, {'name': 'shyam'}];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('misko;shyam;');
|
expect(fixture.debugElement.nativeElement).toHaveText('misko;shyam;');
|
||||||
|
|
||||||
// GROW
|
// GROW
|
||||||
(<any[]>fixture.debugElement.componentInstance.items).push({'name': 'adam'});
|
(<any[]>fixture.debugElement.componentInstance.items).push({'name': 'adam'});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('misko;shyam;adam;');
|
expect(fixture.debugElement.nativeElement).toHaveText('misko;shyam;adam;');
|
||||||
|
|
||||||
// SHRINK
|
// SHRINK
|
||||||
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 2);
|
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 2);
|
||||||
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 0);
|
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 0);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('shyam;');
|
expect(fixture.debugElement.nativeElement).toHaveText('shyam;');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should gracefully handle nulls',
|
it('should gracefully handle nulls',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<ul><li template="ngFor let item of null">{{item}};</li></ul>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.createAsync(TestComponent)
|
var template = '<ul><li template="ngFor let item of null">{{item}};</li></ul>';
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
.then((fixture) => {
|
||||||
async.done();
|
fixture.detectChanges();
|
||||||
});
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
}));
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should gracefully handle ref changing to null and back',
|
it('should gracefully handle ref changing to null and back',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = null;
|
fixture.debugElement.componentInstance.items = null;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [1, 2, 3];
|
fixture.debugElement.componentInstance.items = [1, 2, 3];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('1;2;3;');
|
expect(fixture.debugElement.nativeElement).toHaveText('1;2;3;');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!IS_DART) {
|
if (!IS_DART) {
|
||||||
it('should throw on non-iterable ref and suggest using an array',
|
it('should throw on non-iterable ref and suggest using an array',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
fixture.debugElement.componentInstance.items = 'whaaa';
|
.createAsync(TestComponent)
|
||||||
try {
|
.then((fixture) => {
|
||||||
fixture.detectChanges()
|
fixture.debugElement.componentInstance.items = 'whaaa';
|
||||||
} catch (e) {
|
try {
|
||||||
expect(e.message).toContain(
|
fixture.detectChanges()
|
||||||
`Cannot find a differ supporting object 'whaaa' of type 'string'. NgFor only supports binding to Iterables such as Arrays.`);
|
} catch (e) {
|
||||||
async.done();
|
expect(e.message).toContain(
|
||||||
}
|
`Cannot find a differ supporting object 'whaaa' of type 'string'. NgFor only supports binding to Iterables such as Arrays.`);
|
||||||
});
|
async.done();
|
||||||
}));
|
}
|
||||||
|
});
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should throw on ref changing to string',
|
it('should throw on ref changing to string',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = 'whaaa';
|
fixture.debugElement.componentInstance.items = 'whaaa';
|
||||||
expect(() => fixture.detectChanges()).toThrowError();
|
expect(() => fixture.detectChanges()).toThrowError();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should works with duplicates',
|
it('should works with duplicates',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
.createAsync(TestComponent)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, TEMPLATE)
|
||||||
var a = new Foo();
|
.createAsync(TestComponent)
|
||||||
fixture.debugElement.componentInstance.items = [a, a];
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
var a = new Foo();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('foo;foo;');
|
fixture.debugElement.componentInstance.items = [a, a];
|
||||||
async.done();
|
fixture.detectChanges();
|
||||||
});
|
expect(fixture.debugElement.nativeElement).toHaveText('foo;foo;');
|
||||||
}));
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should repeat over nested arrays',
|
it('should repeat over nested arrays',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div>' +
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div template="ngFor let item of items">' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<div template="ngFor let subitem of item">' +
|
var template = '<div>' +
|
||||||
'{{subitem}}-{{item.length}};' +
|
'<div template="ngFor let item of items">' +
|
||||||
'</div>|' +
|
'<div template="ngFor let subitem of item">' +
|
||||||
'</div>' +
|
'{{subitem}}-{{item.length}};' +
|
||||||
'</div>';
|
'</div>|' +
|
||||||
|
'</div>' +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = [['a', 'b'], ['c']];
|
fixture.debugElement.componentInstance.items = [['a', 'b'], ['c']];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('a-2;b-2;|c-1;|');
|
expect(fixture.debugElement.nativeElement).toHaveText('a-2;b-2;|c-1;|');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [['e'], ['f', 'g']];
|
fixture.debugElement.componentInstance.items = [['e'], ['f', 'g']];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('e-1;|f-2;g-2;|');
|
expect(fixture.debugElement.nativeElement).toHaveText('e-1;|f-2;g-2;|');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should repeat over nested arrays with no intermediate element',
|
it('should repeat over nested arrays with no intermediate element',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div><template ngFor let-item [ngForOf]="items">' +
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div template="ngFor let subitem of item">' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'{{subitem}}-{{item.length}};' +
|
var template = '<div><template ngFor let-item [ngForOf]="items">' +
|
||||||
'</div></template></div>';
|
'<div template="ngFor let subitem of item">' +
|
||||||
|
'{{subitem}}-{{item.length}};' +
|
||||||
|
'</div></template></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = [['a', 'b'], ['c']];
|
fixture.debugElement.componentInstance.items = [['a', 'b'], ['c']];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('a-2;b-2;c-1;');
|
expect(fixture.debugElement.nativeElement).toHaveText('a-2;b-2;c-1;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [['e'], ['f', 'g']];
|
fixture.debugElement.componentInstance.items = [['e'], ['f', 'g']];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('e-1;f-2;g-2;');
|
expect(fixture.debugElement.nativeElement).toHaveText('e-1;f-2;g-2;');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should repeat over nested ngIf that are the last node in the ngFor temlate',
|
it('should repeat over nested ngIf that are the last node in the ngFor temlate',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
`<div><template ngFor let-item [ngForOf]="items" let-i="index"><div>{{i}}|</div>` +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
`<div *ngIf="i % 2 == 0">even|</div></template></div>`;
|
var template =
|
||||||
|
`<div><template ngFor let-item [ngForOf]="items" let-i="index"><div>{{i}}|</div>` +
|
||||||
|
`<div *ngIf="i % 2 == 0">even|</div></template></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var el = fixture.debugElement.nativeElement;
|
var el = fixture.debugElement.nativeElement;
|
||||||
var items = [1];
|
var items = [1];
|
||||||
fixture.debugElement.componentInstance.items = items;
|
fixture.debugElement.componentInstance.items = items;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(el).toHaveText('0|even|');
|
expect(el).toHaveText('0|even|');
|
||||||
|
|
||||||
items.push(1);
|
items.push(1);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(el).toHaveText('0|even|1|');
|
expect(el).toHaveText('0|even|1|');
|
||||||
|
|
||||||
items.push(1);
|
items.push(1);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(el).toHaveText('0|even|1|2|even|');
|
expect(el).toHaveText('0|even|1|2|even|');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should display indices correctly',
|
it('should display indices correctly',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div><copy-me template="ngFor: let item of items; let i=index">{{i.toString()}}</copy-me></div>';
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template =
|
||||||
|
'<div><copy-me template="ngFor: let item of items; let i=index">{{i.toString()}}</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
fixture.debugElement.componentInstance.items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('0123456789');
|
expect(fixture.debugElement.nativeElement).toHaveText('0123456789');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [1, 2, 6, 7, 4, 3, 5, 8, 9, 0];
|
fixture.debugElement.componentInstance.items = [1, 2, 6, 7, 4, 3, 5, 8, 9, 0];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('0123456789');
|
expect(fixture.debugElement.nativeElement).toHaveText('0123456789');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should display first item correctly',
|
it('should display first item correctly',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div><copy-me template="ngFor: let item of items; let isFirst=first">{{isFirst.toString()}}</copy-me></div>';
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template =
|
||||||
|
'<div><copy-me template="ngFor: let item of items; let isFirst=first">{{isFirst.toString()}}</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = [0, 1, 2];
|
fixture.debugElement.componentInstance.items = [0, 1, 2];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('truefalsefalse');
|
expect(fixture.debugElement.nativeElement).toHaveText('truefalsefalse');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [2, 1];
|
fixture.debugElement.componentInstance.items = [2, 1];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('truefalse');
|
expect(fixture.debugElement.nativeElement).toHaveText('truefalse');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should display last item correctly',
|
it('should display last item correctly',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div><copy-me template="ngFor: let item of items; let isLast=last">{{isLast.toString()}}</copy-me></div>';
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template =
|
||||||
|
'<div><copy-me template="ngFor: let item of items; let isLast=last">{{isLast.toString()}}</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = [0, 1, 2];
|
fixture.debugElement.componentInstance.items = [0, 1, 2];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('falsefalsetrue');
|
expect(fixture.debugElement.nativeElement).toHaveText('falsefalsetrue');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [2, 1];
|
fixture.debugElement.componentInstance.items = [2, 1];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('falsetrue');
|
expect(fixture.debugElement.nativeElement).toHaveText('falsetrue');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should display even items correctly',
|
it('should display even items correctly',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div><copy-me template="ngFor: let item of items; let isEven=even">{{isEven.toString()}}</copy-me></div>';
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template =
|
||||||
|
'<div><copy-me template="ngFor: let item of items; let isEven=even">{{isEven.toString()}}</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = [0, 1, 2];
|
fixture.debugElement.componentInstance.items = [0, 1, 2];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('truefalsetrue');
|
expect(fixture.debugElement.nativeElement).toHaveText('truefalsetrue');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [2, 1];
|
fixture.debugElement.componentInstance.items = [2, 1];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('truefalse');
|
expect(fixture.debugElement.nativeElement).toHaveText('truefalse');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should display odd items correctly',
|
it('should display odd items correctly',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div><copy-me template="ngFor: let item of items; let isOdd=odd">{{isOdd.toString()}}</copy-me></div>';
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template =
|
||||||
|
'<div><copy-me template="ngFor: let item of items; let isOdd=odd">{{isOdd.toString()}}</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = [0, 1, 2, 3];
|
fixture.debugElement.componentInstance.items = [0, 1, 2, 3];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('falsetruefalsetrue');
|
expect(fixture.debugElement.nativeElement).toHaveText('falsetruefalsetrue');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.items = [2, 1];
|
fixture.debugElement.componentInstance.items = [2, 1];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('falsetrue');
|
expect(fixture.debugElement.nativeElement).toHaveText('falsetrue');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should allow to use a custom template',
|
it('should allow to use a custom template',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
TestComponent,
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<ul><template ngFor [ngForOf]="items" [ngForTemplate]="contentTpl"></template></ul>')
|
tcb.overrideTemplate(
|
||||||
.overrideTemplate(
|
TestComponent,
|
||||||
ComponentUsingTestComponent,
|
'<ul><template ngFor [ngForOf]="items" [ngForTemplate]="contentTpl"></template></ul>')
|
||||||
'<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>')
|
.overrideTemplate(
|
||||||
.createAsync(ComponentUsingTestComponent)
|
ComponentUsingTestComponent,
|
||||||
.then((fixture) => {
|
'<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>')
|
||||||
var testComponent = fixture.debugElement.children[0];
|
.createAsync(ComponentUsingTestComponent)
|
||||||
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
var testComponent = fixture.debugElement.children[0];
|
||||||
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should use a default template if a custom one is null',
|
it('should use a default template if a custom one is null',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, `<ul><template ngFor let-item [ngForOf]="items"
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
tcb.overrideTemplate(TestComponent, `<ul><template ngFor let-item [ngForOf]="items"
|
||||||
[ngForTemplate]="contentTpl" let-i="index">{{i}}: {{item}};</template></ul>`)
|
[ngForTemplate]="contentTpl" let-i="index">{{i}}: {{item}};</template></ul>`)
|
||||||
.overrideTemplate(ComponentUsingTestComponent, '<test-cmp></test-cmp>')
|
.overrideTemplate(ComponentUsingTestComponent, '<test-cmp></test-cmp>')
|
||||||
.createAsync(ComponentUsingTestComponent)
|
.createAsync(ComponentUsingTestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var testComponent = fixture.debugElement.children[0];
|
var testComponent = fixture.debugElement.children[0];
|
||||||
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should use a custom template when both default and a custom one are present',
|
it('should use a custom template when both default and a custom one are present',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
tcb.overrideTemplate(TestComponent, `<ul><template ngFor let-item [ngForOf]="items"
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
tcb.overrideTemplate(TestComponent, `<ul><template ngFor let-item [ngForOf]="items"
|
||||||
[ngForTemplate]="contentTpl" let-i="index">{{i}}=> {{item}};</template></ul>`)
|
[ngForTemplate]="contentTpl" let-i="index">{{i}}=> {{item}};</template></ul>`)
|
||||||
.overrideTemplate(
|
.overrideTemplate(
|
||||||
ComponentUsingTestComponent,
|
ComponentUsingTestComponent,
|
||||||
'<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>')
|
'<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>')
|
||||||
.createAsync(ComponentUsingTestComponent)
|
.createAsync(ComponentUsingTestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var testComponent = fixture.debugElement.children[0];
|
var testComponent = fixture.debugElement.children[0];
|
||||||
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('track by', function() {
|
describe('track by', function() {
|
||||||
it('should not replace tracked items',
|
it('should not replace tracked items',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
`<template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById" let-i="index">
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template =
|
||||||
|
`<template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById" let-i="index">
|
||||||
<p>{{items[i]}}</p>
|
<p>{{items[i]}}</p>
|
||||||
</template>`;
|
</template>`;
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var buildItemList =
|
var buildItemList =
|
||||||
() => {
|
() => {
|
||||||
fixture.debugElement.componentInstance.items = [{'id': 'a'}];
|
fixture.debugElement.componentInstance.items = [{'id': 'a'}];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
return fixture.debugElement.queryAll(By.css('p'))[0];
|
return fixture.debugElement.queryAll(By.css('p'))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstP = buildItemList();
|
var firstP = buildItemList();
|
||||||
var finalP = buildItemList();
|
var finalP = buildItemList();
|
||||||
expect(finalP.nativeElement).toBe(firstP.nativeElement);
|
expect(finalP.nativeElement).toBe(firstP.nativeElement);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
it('should update implicit local variable on view',
|
it('should update implicit local variable on view',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`;
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
var template =
|
||||||
.createAsync(TestComponent)
|
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`;
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
fixture.debugElement.componentInstance.items = [{'id': 'a', 'color': 'blue'}];
|
.createAsync(TestComponent)
|
||||||
fixture.detectChanges();
|
.then((fixture) => {
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('blue');
|
fixture.debugElement.componentInstance.items = [{'id': 'a', 'color': 'blue'}];
|
||||||
fixture.debugElement.componentInstance.items = [{'id': 'a', 'color': 'red'}];
|
fixture.detectChanges();
|
||||||
fixture.detectChanges();
|
expect(fixture.debugElement.nativeElement).toHaveText('blue');
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('red');
|
fixture.debugElement.componentInstance.items = [{'id': 'a', 'color': 'red'}];
|
||||||
async.done();
|
fixture.detectChanges();
|
||||||
});
|
expect(fixture.debugElement.nativeElement).toHaveText('red');
|
||||||
}));
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
it('should move items around and keep them updated ',
|
it('should move items around and keep them updated ',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`;
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
var template =
|
||||||
.createAsync(TestComponent)
|
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`;
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
fixture.debugElement.componentInstance.items =
|
.createAsync(TestComponent)
|
||||||
[{'id': 'a', 'color': 'blue'}, {'id': 'b', 'color': 'yellow'}];
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.debugElement.componentInstance.items =
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('blueyellow');
|
[{'id': 'a', 'color': 'blue'}, {'id': 'b', 'color': 'yellow'}];
|
||||||
fixture.debugElement.componentInstance.items =
|
fixture.detectChanges();
|
||||||
[{'id': 'b', 'color': 'orange'}, {'id': 'a', 'color': 'red'}];
|
expect(fixture.debugElement.nativeElement).toHaveText('blueyellow');
|
||||||
fixture.detectChanges();
|
fixture.debugElement.componentInstance.items =
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('orangered');
|
[{'id': 'b', 'color': 'orange'}, {'id': 'a', 'color': 'red'}];
|
||||||
async.done();
|
fixture.detectChanges();
|
||||||
});
|
expect(fixture.debugElement.nativeElement).toHaveText('orangered');
|
||||||
}));
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should handle added and removed items properly when tracking by index',
|
it('should handle added and removed items properly when tracking by index',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackByIndex">{{item}}</template></div>`;
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
var template =
|
||||||
.createAsync(TestComponent)
|
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackByIndex">{{item}}</template></div>`;
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
fixture.debugElement.componentInstance.items = ['a', 'b', 'c', 'd'];
|
.createAsync(TestComponent)
|
||||||
fixture.detectChanges();
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.items = ['e', 'f', 'g', 'h'];
|
fixture.debugElement.componentInstance.items = ['a', 'b', 'c', 'd'];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.debugElement.componentInstance.items = ['e', 'f', 'h'];
|
fixture.debugElement.componentInstance.items = ['e', 'f', 'g', 'h'];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('efh');
|
fixture.debugElement.componentInstance.items = ['e', 'f', 'h'];
|
||||||
async.done();
|
fixture.detectChanges();
|
||||||
});
|
expect(fixture.debugElement.nativeElement).toHaveText('efh');
|
||||||
}));
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
import {
|
import {beforeEach, ddescribe, describe, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
beforeEach,
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
iit,
|
|
||||||
inject,
|
|
||||||
it,
|
|
||||||
xit,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {expect} from '@angular/platform-browser/testing';
|
import {expect} from '@angular/platform-browser/testing';
|
||||||
import {TestComponentBuilder} from '@angular/compiler/testing';
|
import {TestComponentBuilder} from '@angular/compiler/testing';
|
||||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
|
@ -21,222 +13,252 @@ import {IS_DART} from '../../src/facade/lang';
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('ngIf directive', () => {
|
describe('ngIf directive', () => {
|
||||||
it('should work in a template attribute',
|
it('should work in a template attribute',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var html = '<div><copy-me template="ngIf booleanCondition">hello</copy-me></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var html = '<div><copy-me template="ngIf booleanCondition">hello</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, html)
|
tcb.overrideTemplate(TestComponent, html)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(1);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
.toEqual(1);
|
||||||
async.done();
|
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||||
});
|
async.done();
|
||||||
}));
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should work in a template element',
|
it('should work in a template element',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var html =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div><template [ngIf]="booleanCondition"><copy-me>hello2</copy-me></template></div>';
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var html =
|
||||||
|
'<div><template [ngIf]="booleanCondition"><copy-me>hello2</copy-me></template></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, html)
|
tcb.overrideTemplate(TestComponent, html)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(1);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('hello2');
|
.toEqual(1);
|
||||||
async.done();
|
expect(fixture.debugElement.nativeElement).toHaveText('hello2');
|
||||||
});
|
async.done();
|
||||||
}));
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should toggle node when condition changes',
|
it('should toggle node when condition changes',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var html = '<div><copy-me template="ngIf booleanCondition">hello</copy-me></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var html = '<div><copy-me template="ngIf booleanCondition">hello</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, html)
|
tcb.overrideTemplate(TestComponent, html)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.booleanCondition = false;
|
fixture.debugElement.componentInstance.booleanCondition = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(0);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
.toEqual(0);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.booleanCondition = true;
|
fixture.debugElement.componentInstance.booleanCondition = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(1);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
.toEqual(1);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.booleanCondition = false;
|
fixture.debugElement.componentInstance.booleanCondition = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(0);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
.toEqual(0);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should handle nested if correctly',
|
it('should handle nested if correctly',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var html =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div><template [ngIf]="booleanCondition"><copy-me *ngIf="nestedBooleanCondition">hello</copy-me></template></div>';
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var html =
|
||||||
|
'<div><template [ngIf]="booleanCondition"><copy-me *ngIf="nestedBooleanCondition">hello</copy-me></template></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, html)
|
tcb.overrideTemplate(TestComponent, html)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.booleanCondition = false;
|
fixture.debugElement.componentInstance.booleanCondition = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(0);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
.toEqual(0);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.booleanCondition = true;
|
fixture.debugElement.componentInstance.booleanCondition = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(1);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
.toEqual(1);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.nestedBooleanCondition = false;
|
fixture.debugElement.componentInstance.nestedBooleanCondition = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(0);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
.toEqual(0);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.nestedBooleanCondition = true;
|
fixture.debugElement.componentInstance.nestedBooleanCondition = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(1);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
.toEqual(1);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.booleanCondition = false;
|
fixture.debugElement.componentInstance.booleanCondition = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(0);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
.toEqual(0);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should update several nodes with if',
|
it('should update several nodes with if',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var html =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div>' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<copy-me template="ngIf numberCondition + 1 >= 2">helloNumber</copy-me>' +
|
var html = '<div>' +
|
||||||
'<copy-me template="ngIf stringCondition == \'foo\'">helloString</copy-me>' +
|
'<copy-me template="ngIf numberCondition + 1 >= 2">helloNumber</copy-me>' +
|
||||||
'<copy-me template="ngIf functionCondition(stringCondition, numberCondition)">helloFunction</copy-me>' +
|
'<copy-me template="ngIf stringCondition == \'foo\'">helloString</copy-me>' +
|
||||||
'</div>';
|
'<copy-me template="ngIf functionCondition(stringCondition, numberCondition)">helloFunction</copy-me>' +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, html)
|
tcb.overrideTemplate(TestComponent, html)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(3);
|
.length)
|
||||||
expect(getDOM().getText(fixture.debugElement.nativeElement))
|
.toEqual(3);
|
||||||
.toEqual('helloNumberhelloStringhelloFunction');
|
expect(getDOM().getText(fixture.debugElement.nativeElement))
|
||||||
|
.toEqual('helloNumberhelloStringhelloFunction');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.numberCondition = 0;
|
fixture.debugElement.componentInstance.numberCondition = 0;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(1);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('helloString');
|
.toEqual(1);
|
||||||
|
expect(fixture.debugElement.nativeElement).toHaveText('helloString');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.numberCondition = 1;
|
fixture.debugElement.componentInstance.numberCondition = 1;
|
||||||
fixture.debugElement.componentInstance.stringCondition = "bar";
|
fixture.debugElement.componentInstance.stringCondition = 'bar';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM()
|
||||||
getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'copy-me').length)
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.toEqual(1);
|
.length)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('helloNumber');
|
.toEqual(1);
|
||||||
async.done();
|
expect(fixture.debugElement.nativeElement).toHaveText('helloNumber');
|
||||||
});
|
async.done();
|
||||||
}));
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
if (!IS_DART) {
|
if (!IS_DART) {
|
||||||
it('should not add the element twice if the condition goes from true to true (JS)',
|
it('should not add the element twice if the condition goes from true to true (JS)',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var html = '<div><copy-me template="ngIf numberCondition">hello</copy-me></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var html = '<div><copy-me template="ngIf numberCondition">hello</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, html)
|
tcb.overrideTemplate(TestComponent, html)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM()
|
expect(getDOM()
|
||||||
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.length)
|
.length)
|
||||||
.toEqual(1);
|
.toEqual(1);
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.numberCondition = 2;
|
fixture.debugElement.componentInstance.numberCondition = 2;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM()
|
expect(getDOM()
|
||||||
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.length)
|
.length)
|
||||||
.toEqual(1);
|
.toEqual(1);
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should not recreate the element if the condition goes from true to true (JS)',
|
it('should not recreate the element if the condition goes from true to true (JS)',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var html = '<div><copy-me template="ngIf numberCondition">hello</copy-me></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var html = '<div><copy-me template="ngIf numberCondition">hello</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, html)
|
tcb.overrideTemplate(TestComponent, html)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
getDOM().addClass(
|
getDOM().addClass(
|
||||||
getDOM().querySelector(fixture.debugElement.nativeElement, 'copy-me'), "foo");
|
getDOM().querySelector(fixture.debugElement.nativeElement, 'copy-me'),
|
||||||
|
'foo');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.numberCondition = 2;
|
fixture.debugElement.componentInstance.numberCondition = 2;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM().hasClass(
|
expect(
|
||||||
getDOM().querySelector(fixture.debugElement.nativeElement, 'copy-me'),
|
getDOM().hasClass(
|
||||||
"foo"))
|
getDOM().querySelector(fixture.debugElement.nativeElement, 'copy-me'),
|
||||||
.toBe(true);
|
'foo'))
|
||||||
|
.toBe(true);
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_DART) {
|
if (IS_DART) {
|
||||||
it('should not create the element if the condition is not a boolean (DART)',
|
it('should not create the element if the condition is not a boolean (DART)',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var html = '<div><copy-me template="ngIf numberCondition">hello</copy-me></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var html = '<div><copy-me template="ngIf numberCondition">hello</copy-me></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, html)
|
tcb.overrideTemplate(TestComponent, html)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
expect(() => fixture.detectChanges()).toThrowError();
|
expect(() => fixture.detectChanges()).toThrowError();
|
||||||
expect(getDOM()
|
expect(getDOM()
|
||||||
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
.querySelectorAll(fixture.debugElement.nativeElement, 'copy-me')
|
||||||
.length)
|
.length)
|
||||||
.toEqual(0);
|
.toEqual(0);
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -253,7 +275,9 @@ class TestComponent {
|
||||||
this.booleanCondition = true;
|
this.booleanCondition = true;
|
||||||
this.nestedBooleanCondition = true;
|
this.nestedBooleanCondition = true;
|
||||||
this.numberCondition = 1;
|
this.numberCondition = 1;
|
||||||
this.stringCondition = "foo";
|
this.stringCondition = 'foo';
|
||||||
this.functionCondition = function(s: any /** TODO #9100 */, n: any /** TODO #9100 */) { return s == "foo" && n == 1; };
|
this.functionCondition = function(s: any /** TODO #9100 */, n: any /** TODO #9100 */) {
|
||||||
|
return s == 'foo' && n == 1;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,4 @@
|
||||||
import {
|
import {beforeEachProviders, beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
beforeEachProviders,
|
|
||||||
beforeEach,
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
iit,
|
|
||||||
inject,
|
|
||||||
it,
|
|
||||||
xit,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
import {TestComponentBuilder} from '@angular/compiler/testing';
|
import {TestComponentBuilder} from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
@ -20,95 +10,102 @@ export function main() {
|
||||||
beforeEachProviders(() => [{provide: NgLocalization, useClass: TestLocalizationMap}]);
|
beforeEachProviders(() => [{provide: NgLocalization, useClass: TestLocalizationMap}]);
|
||||||
|
|
||||||
it('should display the template according to the exact value',
|
it('should display the template according to the exact value',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div>' +
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<ul [ngPlural]="switchValue">' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<template ngPluralCase="=0"><li>you have no messages.</li></template>' +
|
var template = '<div>' +
|
||||||
'<template ngPluralCase="=1"><li>you have one message.</li></template>' +
|
'<ul [ngPlural]="switchValue">' +
|
||||||
'</ul></div>';
|
'<template ngPluralCase="=0"><li>you have no messages.</li></template>' +
|
||||||
|
'<template ngPluralCase="=1"><li>you have one message.</li></template>' +
|
||||||
|
'</ul></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.switchValue = 0;
|
fixture.debugElement.componentInstance.switchValue = 0;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('you have no messages.');
|
expect(fixture.debugElement.nativeElement).toHaveText('you have no messages.');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 1;
|
fixture.debugElement.componentInstance.switchValue = 1;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('you have one message.');
|
expect(fixture.debugElement.nativeElement).toHaveText('you have one message.');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should display the template according to the category',
|
it('should display the template according to the category',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div>' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<ul [ngPlural]="switchValue">' +
|
var template = '<div>' +
|
||||||
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
|
'<ul [ngPlural]="switchValue">' +
|
||||||
'<template ngPluralCase="many"><li>you have many messages.</li></template>' +
|
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
|
||||||
'</ul></div>';
|
'<template ngPluralCase="many"><li>you have many messages.</li></template>' +
|
||||||
|
'</ul></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.switchValue = 2;
|
fixture.debugElement.componentInstance.switchValue = 2;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('you have a few messages.');
|
expect(fixture.debugElement.nativeElement)
|
||||||
|
.toHaveText('you have a few messages.');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 8;
|
fixture.debugElement.componentInstance.switchValue = 8;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('you have many messages.');
|
expect(fixture.debugElement.nativeElement).toHaveText('you have many messages.');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should default to other when no matches are found',
|
it('should default to other when no matches are found',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div>' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<ul [ngPlural]="switchValue">' +
|
var template = '<div>' +
|
||||||
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
|
'<ul [ngPlural]="switchValue">' +
|
||||||
'<template ngPluralCase="other"><li>default message.</li></template>' +
|
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
|
||||||
'</ul></div>';
|
'<template ngPluralCase="other"><li>default message.</li></template>' +
|
||||||
|
'</ul></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.switchValue = 100;
|
fixture.debugElement.componentInstance.switchValue = 100;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('default message.');
|
expect(fixture.debugElement.nativeElement).toHaveText('default message.');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should prioritize value matches over category matches',
|
it('should prioritize value matches over category matches',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<div>' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<ul [ngPlural]="switchValue">' +
|
var template = '<div>' +
|
||||||
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
|
'<ul [ngPlural]="switchValue">' +
|
||||||
'<template ngPluralCase="=2">you have two messages.</template>' +
|
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
|
||||||
'</ul></div>';
|
'<template ngPluralCase="=2">you have two messages.</template>' +
|
||||||
|
'</ul></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.switchValue = 2;
|
fixture.debugElement.componentInstance.switchValue = 2;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('you have two messages.');
|
expect(fixture.debugElement.nativeElement).toHaveText('you have two messages.');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 3;
|
fixture.debugElement.componentInstance.switchValue = 3;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('you have a few messages.');
|
expect(fixture.debugElement.nativeElement)
|
||||||
|
.toHaveText('you have a few messages.');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,4 @@
|
||||||
import {
|
import {beforeEach, beforeEachProviders, ddescribe, xdescribe, describe, expect, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
beforeEach,
|
|
||||||
beforeEachProviders,
|
|
||||||
ddescribe,
|
|
||||||
xdescribe,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
iit,
|
|
||||||
inject,
|
|
||||||
it,
|
|
||||||
xit,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
||||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
|
|
||||||
|
@ -24,128 +13,141 @@ export function main() {
|
||||||
describe('binding to CSS styles', () => {
|
describe('binding to CSS styles', () => {
|
||||||
|
|
||||||
it('should add styles specified in an object literal',
|
it('should add styles specified in an object literal',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngStyle]="{'max-width': '40px'}"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngStyle]="{'max-width': '40px'}"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
.toEqual('40px');
|
.toEqual('40px');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should add and change styles specified in an object expression',
|
it('should add and change styles specified in an object expression',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngStyle]="expr"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngStyle]="expr"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var expr: Map<string, any>;
|
var expr: Map<string, any>;
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
.toEqual('40px');
|
.toEqual('40px');
|
||||||
|
|
||||||
expr = fixture.debugElement.componentInstance.expr;
|
expr = fixture.debugElement.componentInstance.expr;
|
||||||
(expr as any /** TODO #9100 */)['max-width'] = '30%';
|
(expr as any /** TODO #9100 */)['max-width'] = '30%';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
.toEqual('30%');
|
.toEqual('30%');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should remove styles when deleting a key in an object expression',
|
it('should remove styles when deleting a key in an object expression',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [ngStyle]="expr"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [ngStyle]="expr"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
.toEqual('40px');
|
.toEqual('40px');
|
||||||
|
|
||||||
StringMapWrapper.delete(fixture.debugElement.componentInstance.expr, 'max-width');
|
StringMapWrapper.delete(
|
||||||
fixture.detectChanges();
|
fixture.debugElement.componentInstance.expr, 'max-width');
|
||||||
expect(
|
fixture.detectChanges();
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
expect(getDOM().getStyle(
|
||||||
.toEqual('');
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
|
.toEqual('');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should co-operate with the style attribute',
|
it('should co-operate with the style attribute',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div style="font-size: 12px" [ngStyle]="expr"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div style="font-size: 12px" [ngStyle]="expr"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
.toEqual('40px');
|
.toEqual('40px');
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'font-size'))
|
fixture.debugElement.children[0].nativeElement, 'font-size'))
|
||||||
.toEqual('12px');
|
.toEqual('12px');
|
||||||
|
|
||||||
StringMapWrapper.delete(fixture.debugElement.componentInstance.expr, 'max-width');
|
StringMapWrapper.delete(
|
||||||
fixture.detectChanges();
|
fixture.debugElement.componentInstance.expr, 'max-width');
|
||||||
expect(
|
fixture.detectChanges();
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
expect(getDOM().getStyle(
|
||||||
.toEqual('');
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
expect(
|
.toEqual('');
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'font-size'))
|
expect(getDOM().getStyle(
|
||||||
.toEqual('12px');
|
fixture.debugElement.children[0].nativeElement, 'font-size'))
|
||||||
|
.toEqual('12px');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should co-operate with the style.[styleName]="expr" special-case in the compiler',
|
it('should co-operate with the style.[styleName]="expr" special-case in the compiler',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<div [style.font-size.px]="12" [ngStyle]="expr"></div>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var template = `<div [style.font-size.px]="12" [ngStyle]="expr"></div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
.toEqual('40px');
|
.toEqual('40px');
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'font-size'))
|
fixture.debugElement.children[0].nativeElement, 'font-size'))
|
||||||
.toEqual('12px');
|
.toEqual('12px');
|
||||||
|
|
||||||
StringMapWrapper.delete(fixture.debugElement.componentInstance.expr, 'max-width');
|
StringMapWrapper.delete(
|
||||||
expect(
|
fixture.debugElement.componentInstance.expr, 'max-width');
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'font-size'))
|
expect(getDOM().getStyle(
|
||||||
.toEqual('12px');
|
fixture.debugElement.children[0].nativeElement, 'font-size'))
|
||||||
|
.toEqual('12px');
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(
|
expect(getDOM().getStyle(
|
||||||
getDOM().getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||||
.toEqual('');
|
.toEqual('');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
import {
|
import {beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
beforeEach,
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
iit,
|
|
||||||
inject,
|
|
||||||
it,
|
|
||||||
xit,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
||||||
|
@ -18,127 +9,135 @@ export function main() {
|
||||||
describe('switch', () => {
|
describe('switch', () => {
|
||||||
describe('switch value changes', () => {
|
describe('switch value changes', () => {
|
||||||
it('should switch amongst when values',
|
it('should switch amongst when values',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div>' +
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<ul [ngSwitch]="switchValue">' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<template ngSwitchWhen="a"><li>when a</li></template>' +
|
var template = '<div>' +
|
||||||
'<template ngSwitchWhen="b"><li>when b</li></template>' +
|
'<ul [ngSwitch]="switchValue">' +
|
||||||
'</ul></div>';
|
'<template ngSwitchWhen="a"><li>when a</li></template>' +
|
||||||
|
'<template ngSwitchWhen="b"><li>when b</li></template>' +
|
||||||
|
'</ul></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 'a';
|
fixture.debugElement.componentInstance.switchValue = 'a';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when a');
|
expect(fixture.debugElement.nativeElement).toHaveText('when a');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 'b';
|
fixture.debugElement.componentInstance.switchValue = 'b';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when b');
|
expect(fixture.debugElement.nativeElement).toHaveText('when b');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should switch amongst when values with fallback to default',
|
it('should switch amongst when values with fallback to default',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div>' +
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<ul [ngSwitch]="switchValue">' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<li template="ngSwitchWhen \'a\'">when a</li>' +
|
var template = '<div>' +
|
||||||
'<li template="ngSwitchDefault">when default</li>' +
|
'<ul [ngSwitch]="switchValue">' +
|
||||||
'</ul></div>';
|
'<li template="ngSwitchWhen \'a\'">when a</li>' +
|
||||||
|
'<li template="ngSwitchDefault">when default</li>' +
|
||||||
|
'</ul></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when default');
|
expect(fixture.debugElement.nativeElement).toHaveText('when default');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 'a';
|
fixture.debugElement.componentInstance.switchValue = 'a';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when a');
|
expect(fixture.debugElement.nativeElement).toHaveText('when a');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 'b';
|
fixture.debugElement.componentInstance.switchValue = 'b';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when default');
|
expect(fixture.debugElement.nativeElement).toHaveText('when default');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should support multiple whens with the same value',
|
it('should support multiple whens with the same value',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div>' +
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<ul [ngSwitch]="switchValue">' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<template ngSwitchWhen="a"><li>when a1;</li></template>' +
|
var template = '<div>' +
|
||||||
'<template ngSwitchWhen="b"><li>when b1;</li></template>' +
|
'<ul [ngSwitch]="switchValue">' +
|
||||||
'<template ngSwitchWhen="a"><li>when a2;</li></template>' +
|
'<template ngSwitchWhen="a"><li>when a1;</li></template>' +
|
||||||
'<template ngSwitchWhen="b"><li>when b2;</li></template>' +
|
'<template ngSwitchWhen="b"><li>when b1;</li></template>' +
|
||||||
'<template ngSwitchDefault><li>when default1;</li></template>' +
|
'<template ngSwitchWhen="a"><li>when a2;</li></template>' +
|
||||||
'<template ngSwitchDefault><li>when default2;</li></template>' +
|
'<template ngSwitchWhen="b"><li>when b2;</li></template>' +
|
||||||
'</ul></div>';
|
'<template ngSwitchDefault><li>when default1;</li></template>' +
|
||||||
|
'<template ngSwitchDefault><li>when default2;</li></template>' +
|
||||||
|
'</ul></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement)
|
expect(fixture.debugElement.nativeElement)
|
||||||
.toHaveText('when default1;when default2;');
|
.toHaveText('when default1;when default2;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 'a';
|
fixture.debugElement.componentInstance.switchValue = 'a';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when a1;when a2;');
|
expect(fixture.debugElement.nativeElement).toHaveText('when a1;when a2;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 'b';
|
fixture.debugElement.componentInstance.switchValue = 'b';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when b1;when b2;');
|
expect(fixture.debugElement.nativeElement).toHaveText('when b1;when b2;');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when values changes', () => {
|
describe('when values changes', () => {
|
||||||
it('should switch amongst when values',
|
it('should switch amongst when values',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div>' +
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
'<ul [ngSwitch]="switchValue">' +
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
'<template [ngSwitchWhen]="when1"><li>when 1;</li></template>' +
|
var template = '<div>' +
|
||||||
'<template [ngSwitchWhen]="when2"><li>when 2;</li></template>' +
|
'<ul [ngSwitch]="switchValue">' +
|
||||||
'<template ngSwitchDefault><li>when default;</li></template>' +
|
'<template [ngSwitchWhen]="when1"><li>when 1;</li></template>' +
|
||||||
'</ul></div>';
|
'<template [ngSwitchWhen]="when2"><li>when 2;</li></template>' +
|
||||||
|
'<template ngSwitchDefault><li>when default;</li></template>' +
|
||||||
|
'</ul></div>';
|
||||||
|
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
.createAsync(TestComponent)
|
.createAsync(TestComponent)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.when1 = 'a';
|
fixture.debugElement.componentInstance.when1 = 'a';
|
||||||
fixture.debugElement.componentInstance.when2 = 'b';
|
fixture.debugElement.componentInstance.when2 = 'b';
|
||||||
fixture.debugElement.componentInstance.switchValue = 'a';
|
fixture.debugElement.componentInstance.switchValue = 'a';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when 1;');
|
expect(fixture.debugElement.nativeElement).toHaveText('when 1;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 'b';
|
fixture.debugElement.componentInstance.switchValue = 'b';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when 2;');
|
expect(fixture.debugElement.nativeElement).toHaveText('when 2;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.switchValue = 'c';
|
fixture.debugElement.componentInstance.switchValue = 'c';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when default;');
|
expect(fixture.debugElement.nativeElement).toHaveText('when default;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.when1 = 'c';
|
fixture.debugElement.componentInstance.when1 = 'c';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when 1;');
|
expect(fixture.debugElement.nativeElement).toHaveText('when 1;');
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.when1 = 'd';
|
fixture.debugElement.componentInstance.when1 = 'd';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('when default;');
|
expect(fixture.debugElement.nativeElement).toHaveText('when default;');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
import {
|
import {beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
beforeEach,
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
iit,
|
|
||||||
inject,
|
|
||||||
it,
|
|
||||||
xit,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
||||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
import {Component, Directive, TemplateRef, ContentChildren, QueryList} from '@angular/core';
|
import {Component, Directive, TemplateRef, ContentChildren, QueryList} from '@angular/core';
|
||||||
|
@ -16,84 +7,93 @@ import {NgTemplateOutlet} from '@angular/common';
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('insert', () => {
|
describe('insert', () => {
|
||||||
it('should do nothing if templateRef is null',
|
it('should do nothing if templateRef is null',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<template [ngTemplateOutlet]="null"></template>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.createAsync(TestComponent)
|
var template = `<template [ngTemplateOutlet]="null"></template>`;
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
|
.createAsync(TestComponent)
|
||||||
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.nativeElement).toHaveText('');
|
expect(fixture.nativeElement).toHaveText('');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should insert content specified by TemplateRef',
|
it('should insert content specified by TemplateRef',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
`<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
var template =
|
||||||
.createAsync(TestComponent)
|
`<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
|
.createAsync(TestComponent)
|
||||||
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.nativeElement).toHaveText('');
|
expect(fixture.nativeElement).toHaveText('');
|
||||||
|
|
||||||
var refs = fixture.debugElement.children[0].references['refs'];
|
var refs = fixture.debugElement.children[0].references['refs'];
|
||||||
|
|
||||||
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
|
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.nativeElement).toHaveText('foo');
|
expect(fixture.nativeElement).toHaveText('foo');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should clear content if TemplateRef becomes null',
|
it('should clear content if TemplateRef becomes null',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template =
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
`<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
var template =
|
||||||
.createAsync(TestComponent)
|
`<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
|
.createAsync(TestComponent)
|
||||||
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
var refs = fixture.debugElement.children[0].references['refs'];
|
var refs = fixture.debugElement.children[0].references['refs'];
|
||||||
|
|
||||||
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
|
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.nativeElement).toHaveText('foo');
|
expect(fixture.nativeElement).toHaveText('foo');
|
||||||
|
|
||||||
fixture.componentInstance.currentTplRef = null;
|
fixture.componentInstance.currentTplRef = null;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.nativeElement).toHaveText('');
|
expect(fixture.nativeElement).toHaveText('');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should swap content if TemplateRef changes',
|
it('should swap content if TemplateRef changes',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = `<tpl-refs #refs="tplRefs"><template>foo</template><template>bar</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.createAsync(TestComponent)
|
var template =
|
||||||
.then((fixture) => {
|
`<tpl-refs #refs="tplRefs"><template>foo</template><template>bar</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
|
||||||
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
|
.createAsync(TestComponent)
|
||||||
|
.then((fixture) => {
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
var refs = fixture.debugElement.children[0].references['refs'];
|
var refs = fixture.debugElement.children[0].references['refs'];
|
||||||
|
|
||||||
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
|
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.nativeElement).toHaveText('foo');
|
expect(fixture.nativeElement).toHaveText('foo');
|
||||||
|
|
||||||
fixture.componentInstance.currentTplRef = refs.tplRefs.last;
|
fixture.componentInstance.currentTplRef = refs.tplRefs.last;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.nativeElement).toHaveText('bar');
|
expect(fixture.nativeElement).toHaveText('bar');
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
import {
|
import {beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
beforeEach,
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
iit,
|
|
||||||
inject,
|
|
||||||
it,
|
|
||||||
xit,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
import {Component, Directive} from '@angular/core';
|
import {Component, Directive} from '@angular/core';
|
||||||
|
@ -17,45 +8,51 @@ import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('non-bindable', () => {
|
describe('non-bindable', () => {
|
||||||
it('should not interpolate children',
|
it('should not interpolate children',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div>{{text}}<span ngNonBindable>{{text}}</span></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.createAsync(TestComponent)
|
var template = '<div>{{text}}<span ngNonBindable>{{text}}</span></div>';
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
expect(fixture.debugElement.nativeElement).toHaveText('foo{{text}}');
|
.then((fixture) => {
|
||||||
async.done();
|
fixture.detectChanges();
|
||||||
});
|
expect(fixture.debugElement.nativeElement).toHaveText('foo{{text}}');
|
||||||
}));
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should ignore directives on child nodes',
|
it('should ignore directives on child nodes',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div ngNonBindable><span id=child test-dec>{{text}}</span></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.createAsync(TestComponent)
|
var template = '<div ngNonBindable><span id=child test-dec>{{text}}</span></div>';
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
// We must use getDOM().querySelector instead of fixture.query here
|
// We must use getDOM().querySelector instead of fixture.query here
|
||||||
// since the elements inside are not compiled.
|
// since the elements inside are not compiled.
|
||||||
var span = getDOM().querySelector(fixture.debugElement.nativeElement, '#child');
|
var span = getDOM().querySelector(fixture.debugElement.nativeElement, '#child');
|
||||||
expect(getDOM().hasClass(span, 'compiled')).toBeFalsy();
|
expect(getDOM().hasClass(span, 'compiled')).toBeFalsy();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should trigger directives on the same node',
|
it('should trigger directives on the same node',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
inject(
|
||||||
var template = '<div><span id=child ngNonBindable test-dec>{{text}}</span></div>';
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
tcb.overrideTemplate(TestComponent, template)
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
.createAsync(TestComponent)
|
var template = '<div><span id=child ngNonBindable test-dec>{{text}}</span></div>';
|
||||||
.then((fixture) => {
|
tcb.overrideTemplate(TestComponent, template)
|
||||||
fixture.detectChanges();
|
.createAsync(TestComponent)
|
||||||
var span = getDOM().querySelector(fixture.debugElement.nativeElement, '#child');
|
.then((fixture) => {
|
||||||
expect(getDOM().hasClass(span, 'compiled')).toBeTruthy();
|
fixture.detectChanges();
|
||||||
async.done();
|
var span = getDOM().querySelector(fixture.debugElement.nativeElement, '#child');
|
||||||
});
|
expect(getDOM().hasClass(span, 'compiled')).toBeTruthy();
|
||||||
}));
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,41 +1,10 @@
|
||||||
import {
|
import {afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach,
|
|
||||||
inject
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
|
|
||||||
import {
|
import {fakeAsync, flushMicrotasks, Log, tick,} from '@angular/core/testing';
|
||||||
fakeAsync,
|
|
||||||
flushMicrotasks,
|
|
||||||
Log,
|
|
||||||
tick,
|
|
||||||
} from '@angular/core/testing';
|
|
||||||
|
|
||||||
import {SpyNgControl, SpyValueAccessor} from '../spies';
|
import {SpyNgControl, SpyValueAccessor} from '../spies';
|
||||||
|
|
||||||
import {
|
import {ControlGroup, Control, NgControlName, NgControlGroup, NgFormModel, ControlValueAccessor, Validators, NgForm, NgModel, NgFormControl, NgControl, DefaultValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, Validator} from '@angular/common';
|
||||||
ControlGroup,
|
|
||||||
Control,
|
|
||||||
NgControlName,
|
|
||||||
NgControlGroup,
|
|
||||||
NgFormModel,
|
|
||||||
ControlValueAccessor,
|
|
||||||
Validators,
|
|
||||||
NgForm,
|
|
||||||
NgModel,
|
|
||||||
NgFormControl,
|
|
||||||
NgControl,
|
|
||||||
DefaultValueAccessor,
|
|
||||||
CheckboxControlValueAccessor,
|
|
||||||
SelectControlValueAccessor,
|
|
||||||
Validator
|
|
||||||
} from '@angular/common';
|
|
||||||
|
|
||||||
|
|
||||||
import {selectValueAccessor, composeValidators} from '@angular/common/src/forms-deprecated/directives/shared';
|
import {selectValueAccessor, composeValidators} from '@angular/common/src/forms-deprecated/directives/shared';
|
||||||
|
@ -53,13 +22,13 @@ class DummyControlValueAccessor implements ControlValueAccessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomValidatorDirective implements Validator {
|
class CustomValidatorDirective implements Validator {
|
||||||
validate(c: Control): {[key: string]: any} { return {"custom": true}; }
|
validate(c: Control): {[key: string]: any} { return {'custom': true}; }
|
||||||
}
|
}
|
||||||
|
|
||||||
function asyncValidator(expected: any /** TODO #9100 */, timeout = 0) {
|
function asyncValidator(expected: any /** TODO #9100 */, timeout = 0) {
|
||||||
return (c: any /** TODO #9100 */) => {
|
return (c: any /** TODO #9100 */) => {
|
||||||
var completer = PromiseWrapper.completer();
|
var completer = PromiseWrapper.completer();
|
||||||
var res = c.value != expected ? {"async": true} : null;
|
var res = c.value != expected ? {'async': true} : null;
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
completer.resolve(res);
|
completer.resolve(res);
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,71 +39,73 @@ function asyncValidator(expected: any /** TODO #9100 */, timeout = 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe("Form Directives", () => {
|
describe('Form Directives', () => {
|
||||||
var defaultAccessor: DefaultValueAccessor;
|
var defaultAccessor: DefaultValueAccessor;
|
||||||
|
|
||||||
beforeEach(() => { defaultAccessor = new DefaultValueAccessor(null, null); });
|
beforeEach(() => { defaultAccessor = new DefaultValueAccessor(null, null); });
|
||||||
|
|
||||||
describe("shared", () => {
|
describe('shared', () => {
|
||||||
describe("selectValueAccessor", () => {
|
describe('selectValueAccessor', () => {
|
||||||
var dir: NgControl;
|
var dir: NgControl;
|
||||||
|
|
||||||
beforeEach(() => { dir = <any>new SpyNgControl(); });
|
beforeEach(() => { dir = <any>new SpyNgControl(); });
|
||||||
|
|
||||||
it("should throw when given an empty array",
|
it('should throw when given an empty array',
|
||||||
() => { expect(() => selectValueAccessor(dir, [])).toThrowError(); });
|
() => { expect(() => selectValueAccessor(dir, [])).toThrowError(); });
|
||||||
|
|
||||||
it("should return the default value accessor when no other provided",
|
it('should return the default value accessor when no other provided',
|
||||||
() => { expect(selectValueAccessor(dir, [defaultAccessor])).toEqual(defaultAccessor); });
|
() => { expect(selectValueAccessor(dir, [defaultAccessor])).toEqual(defaultAccessor); });
|
||||||
|
|
||||||
it("should return checkbox accessor when provided", () => {
|
it('should return checkbox accessor when provided', () => {
|
||||||
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
||||||
expect(selectValueAccessor(dir, [defaultAccessor, checkboxAccessor]))
|
expect(selectValueAccessor(dir, [
|
||||||
.toEqual(checkboxAccessor);
|
defaultAccessor, checkboxAccessor
|
||||||
|
])).toEqual(checkboxAccessor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return select accessor when provided", () => {
|
it('should return select accessor when provided', () => {
|
||||||
var selectAccessor = new SelectControlValueAccessor(null, null);
|
var selectAccessor = new SelectControlValueAccessor(null, null);
|
||||||
expect(selectValueAccessor(dir, [defaultAccessor, selectAccessor]))
|
expect(selectValueAccessor(dir, [
|
||||||
.toEqual(selectAccessor);
|
defaultAccessor, selectAccessor
|
||||||
|
])).toEqual(selectAccessor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when more than one build-in accessor is provided", () => {
|
it('should throw when more than one build-in accessor is provided', () => {
|
||||||
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
||||||
var selectAccessor = new SelectControlValueAccessor(null, null);
|
var selectAccessor = new SelectControlValueAccessor(null, null);
|
||||||
expect(() => selectValueAccessor(dir, [checkboxAccessor, selectAccessor])).toThrowError();
|
expect(() => selectValueAccessor(dir, [checkboxAccessor, selectAccessor])).toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return custom accessor when provided", () => {
|
it('should return custom accessor when provided', () => {
|
||||||
var customAccessor = new SpyValueAccessor();
|
var customAccessor = new SpyValueAccessor();
|
||||||
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
||||||
expect(selectValueAccessor(dir, <any>[defaultAccessor, customAccessor, checkboxAccessor]))
|
expect(selectValueAccessor(dir, <any>[defaultAccessor, customAccessor, checkboxAccessor]))
|
||||||
.toEqual(customAccessor);
|
.toEqual(customAccessor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when more than one custom accessor is provided", () => {
|
it('should throw when more than one custom accessor is provided', () => {
|
||||||
var customAccessor: ControlValueAccessor = <any>new SpyValueAccessor();
|
var customAccessor: ControlValueAccessor = <any>new SpyValueAccessor();
|
||||||
expect(() => selectValueAccessor(dir, [customAccessor, customAccessor])).toThrowError();
|
expect(() => selectValueAccessor(dir, [customAccessor, customAccessor])).toThrowError();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("composeValidators", () => {
|
describe('composeValidators', () => {
|
||||||
it("should compose functions", () => {
|
it('should compose functions', () => {
|
||||||
var dummy1 = (_: any /** TODO #9100 */) => ({"dummy1": true});
|
var dummy1 = (_: any /** TODO #9100 */) => ({'dummy1': true});
|
||||||
var dummy2 = (_: any /** TODO #9100 */) => ({"dummy2": true});
|
var dummy2 = (_: any /** TODO #9100 */) => ({'dummy2': true});
|
||||||
var v = composeValidators([dummy1, dummy2]);
|
var v = composeValidators([dummy1, dummy2]);
|
||||||
expect(v(new Control(""))).toEqual({"dummy1": true, "dummy2": true});
|
expect(v(new Control(''))).toEqual({'dummy1': true, 'dummy2': true});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should compose validator directives", () => {
|
it('should compose validator directives', () => {
|
||||||
var dummy1 = (_: any /** TODO #9100 */) => ({"dummy1": true});
|
var dummy1 = (_: any /** TODO #9100 */) => ({'dummy1': true});
|
||||||
var v = composeValidators([dummy1, new CustomValidatorDirective()]);
|
var v = composeValidators([dummy1, new CustomValidatorDirective()]);
|
||||||
expect(v(new Control(""))).toEqual({"dummy1": true, "custom": true});
|
expect(v(new Control(''))).toEqual({'dummy1': true, 'custom': true});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgFormModel", () => {
|
describe('NgFormModel', () => {
|
||||||
var form: any /** TODO #9100 */;
|
var form: any /** TODO #9100 */;
|
||||||
var formModel: ControlGroup;
|
var formModel: ControlGroup;
|
||||||
var loginControlDir: any /** TODO #9100 */;
|
var loginControlDir: any /** TODO #9100 */;
|
||||||
|
@ -142,19 +113,19 @@ export function main() {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
form = new NgFormModel([], []);
|
form = new NgFormModel([], []);
|
||||||
formModel = new ControlGroup({
|
formModel = new ControlGroup({
|
||||||
"login": new Control(),
|
'login': new Control(),
|
||||||
"passwords":
|
'passwords':
|
||||||
new ControlGroup({"password": new Control(), "passwordConfirm": new Control()})
|
new ControlGroup({'password': new Control(), 'passwordConfirm': new Control()})
|
||||||
});
|
});
|
||||||
form.form = formModel;
|
form.form = formModel;
|
||||||
|
|
||||||
loginControlDir = new NgControlName(form, [Validators.required],
|
loginControlDir = new NgControlName(
|
||||||
[asyncValidator("expected")], [defaultAccessor]);
|
form, [Validators.required], [asyncValidator('expected')], [defaultAccessor]);
|
||||||
loginControlDir.name = "login";
|
loginControlDir.name = 'login';
|
||||||
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
expect(form.control).toBe(formModel);
|
expect(form.control).toBe(formModel);
|
||||||
expect(form.value).toBe(formModel.value);
|
expect(form.value).toBe(formModel.value);
|
||||||
expect(form.valid).toBe(formModel.valid);
|
expect(form.valid).toBe(formModel.valid);
|
||||||
|
@ -165,130 +136,132 @@ export function main() {
|
||||||
expect(form.untouched).toBe(formModel.untouched);
|
expect(form.untouched).toBe(formModel.untouched);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("addControl", () => {
|
describe('addControl', () => {
|
||||||
it("should throw when no control found", () => {
|
it('should throw when no control found', () => {
|
||||||
var dir = new NgControlName(form, null, null, [defaultAccessor]);
|
var dir = new NgControlName(form, null, null, [defaultAccessor]);
|
||||||
dir.name = "invalidName";
|
dir.name = 'invalidName';
|
||||||
|
|
||||||
expect(() => form.addControl(dir))
|
expect(() => form.addControl(dir))
|
||||||
.toThrowError(new RegExp("Cannot find control 'invalidName'"));
|
.toThrowError(new RegExp('Cannot find control \'invalidName\''));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when no value accessor", () => {
|
it('should throw when no value accessor', () => {
|
||||||
var dir = new NgControlName(form, null, null, null);
|
var dir = new NgControlName(form, null, null, null);
|
||||||
dir.name = "login";
|
dir.name = 'login';
|
||||||
|
|
||||||
expect(() => form.addControl(dir))
|
expect(() => form.addControl(dir))
|
||||||
.toThrowError(new RegExp("No value accessor for 'login'"));
|
.toThrowError(new RegExp('No value accessor for \'login\''));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validators", fakeAsync(() => {
|
it('should set up validators', fakeAsync(() => {
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
// sync validators are set
|
// sync validators are set
|
||||||
expect(formModel.hasError("required", ["login"])).toBe(true);
|
expect(formModel.hasError('required', ['login'])).toBe(true);
|
||||||
expect(formModel.hasError("async", ["login"])).toBe(false);
|
expect(formModel.hasError('async', ['login'])).toBe(false);
|
||||||
|
|
||||||
(<Control>formModel.find(["login"])).updateValue("invalid value");
|
(<Control>formModel.find(['login'])).updateValue('invalid value');
|
||||||
|
|
||||||
// sync validator passes, running async validators
|
// sync validator passes, running async validators
|
||||||
expect(formModel.pending).toBe(true);
|
expect(formModel.pending).toBe(true);
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(formModel.hasError("required", ["login"])).toBe(false);
|
expect(formModel.hasError('required', ['login'])).toBe(false);
|
||||||
expect(formModel.hasError("async", ["login"])).toBe(true);
|
expect(formModel.hasError('async', ['login'])).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should write value to the DOM", () => {
|
it('should write value to the DOM', () => {
|
||||||
(<Control>formModel.find(["login"])).updateValue("initValue");
|
(<Control>formModel.find(['login'])).updateValue('initValue');
|
||||||
|
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual("initValue");
|
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual('initValue');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should add the directive to the list of directives included in the form", () => {
|
it('should add the directive to the list of directives included in the form', () => {
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
expect(form.directives).toEqual([loginControlDir]);
|
expect(form.directives).toEqual([loginControlDir]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("addControlGroup", () => {
|
describe('addControlGroup', () => {
|
||||||
var matchingPasswordsValidator = (g: any /** TODO #9100 */) => {
|
var matchingPasswordsValidator = (g: any /** TODO #9100 */) => {
|
||||||
if (g.controls["password"].value != g.controls["passwordConfirm"].value) {
|
if (g.controls['password'].value != g.controls['passwordConfirm'].value) {
|
||||||
return {"differentPasswords": true};
|
return {'differentPasswords': true};
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
it("should set up validator", fakeAsync(() => {
|
it('should set up validator', fakeAsync(() => {
|
||||||
var group = new NgControlGroup(form, [matchingPasswordsValidator],
|
var group = new NgControlGroup(
|
||||||
[asyncValidator('expected')]);
|
form, [matchingPasswordsValidator], [asyncValidator('expected')]);
|
||||||
group.name = "passwords";
|
group.name = 'passwords';
|
||||||
form.addControlGroup(group);
|
form.addControlGroup(group);
|
||||||
|
|
||||||
(<Control>formModel.find(["passwords", "password"])).updateValue("somePassword");
|
(<Control>formModel.find(['passwords', 'password'])).updateValue('somePassword');
|
||||||
(<Control>formModel.find(["passwords", "passwordConfirm"]))
|
(<Control>formModel.find([
|
||||||
.updateValue("someOtherPassword");
|
'passwords', 'passwordConfirm'
|
||||||
|
])).updateValue('someOtherPassword');
|
||||||
|
|
||||||
// sync validators are set
|
// sync validators are set
|
||||||
expect(formModel.hasError("differentPasswords", ["passwords"])).toEqual(true);
|
expect(formModel.hasError('differentPasswords', ['passwords'])).toEqual(true);
|
||||||
|
|
||||||
(<Control>formModel.find(["passwords", "passwordConfirm"]))
|
(<Control>formModel.find([
|
||||||
.updateValue("somePassword");
|
'passwords', 'passwordConfirm'
|
||||||
|
])).updateValue('somePassword');
|
||||||
|
|
||||||
// sync validators pass, running async validators
|
// sync validators pass, running async validators
|
||||||
expect(formModel.pending).toBe(true);
|
expect(formModel.pending).toBe(true);
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(formModel.hasError("async", ["passwords"])).toBe(true);
|
expect(formModel.hasError('async', ['passwords'])).toBe(true);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("removeControl", () => {
|
describe('removeControl', () => {
|
||||||
it("should remove the directive to the list of directives included in the form", () => {
|
it('should remove the directive to the list of directives included in the form', () => {
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
form.removeControl(loginControlDir);
|
form.removeControl(loginControlDir);
|
||||||
expect(form.directives).toEqual([]);
|
expect(form.directives).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("ngOnChanges", () => {
|
describe('ngOnChanges', () => {
|
||||||
it("should update dom values of all the directives", () => {
|
it('should update dom values of all the directives', () => {
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
(<Control>formModel.find(["login"])).updateValue("new value");
|
(<Control>formModel.find(['login'])).updateValue('new value');
|
||||||
|
|
||||||
form.ngOnChanges({});
|
form.ngOnChanges({});
|
||||||
|
|
||||||
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual("new value");
|
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual('new value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up a sync validator", () => {
|
it('should set up a sync validator', () => {
|
||||||
var formValidator = (c: any /** TODO #9100 */) => ({"custom": true});
|
var formValidator = (c: any /** TODO #9100 */) => ({'custom': true});
|
||||||
var f = new NgFormModel([formValidator], []);
|
var f = new NgFormModel([formValidator], []);
|
||||||
f.form = formModel;
|
f.form = formModel;
|
||||||
f.ngOnChanges({"form": new SimpleChange(null, null)});
|
f.ngOnChanges({'form': new SimpleChange(null, null)});
|
||||||
|
|
||||||
expect(formModel.errors).toEqual({"custom": true});
|
expect(formModel.errors).toEqual({'custom': true});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up an async validator", fakeAsync(() => {
|
it('should set up an async validator', fakeAsync(() => {
|
||||||
var f = new NgFormModel([], [asyncValidator("expected")]);
|
var f = new NgFormModel([], [asyncValidator('expected')]);
|
||||||
f.form = formModel;
|
f.form = formModel;
|
||||||
f.ngOnChanges({"form": new SimpleChange(null, null)});
|
f.ngOnChanges({'form': new SimpleChange(null, null)});
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(formModel.errors).toEqual({"async": true});
|
expect(formModel.errors).toEqual({'async': true});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgForm", () => {
|
describe('NgForm', () => {
|
||||||
var form: any /** TODO #9100 */;
|
var form: any /** TODO #9100 */;
|
||||||
var formModel: ControlGroup;
|
var formModel: ControlGroup;
|
||||||
var loginControlDir: any /** TODO #9100 */;
|
var loginControlDir: any /** TODO #9100 */;
|
||||||
|
@ -299,14 +272,14 @@ export function main() {
|
||||||
formModel = form.form;
|
formModel = form.form;
|
||||||
|
|
||||||
personControlGroupDir = new NgControlGroup(form, [], []);
|
personControlGroupDir = new NgControlGroup(form, [], []);
|
||||||
personControlGroupDir.name = "person";
|
personControlGroupDir.name = 'person';
|
||||||
|
|
||||||
loginControlDir = new NgControlName(personControlGroupDir, null, null, [defaultAccessor]);
|
loginControlDir = new NgControlName(personControlGroupDir, null, null, [defaultAccessor]);
|
||||||
loginControlDir.name = "login";
|
loginControlDir.name = 'login';
|
||||||
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
expect(form.control).toBe(formModel);
|
expect(form.control).toBe(formModel);
|
||||||
expect(form.value).toBe(formModel.value);
|
expect(form.value).toBe(formModel.value);
|
||||||
expect(form.valid).toBe(formModel.valid);
|
expect(form.valid).toBe(formModel.valid);
|
||||||
|
@ -317,21 +290,21 @@ export function main() {
|
||||||
expect(form.untouched).toBe(formModel.untouched);
|
expect(form.untouched).toBe(formModel.untouched);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("addControl & addControlGroup", () => {
|
describe('addControl & addControlGroup', () => {
|
||||||
it("should create a control with the given name", fakeAsync(() => {
|
it('should create a control with the given name', fakeAsync(() => {
|
||||||
form.addControlGroup(personControlGroupDir);
|
form.addControlGroup(personControlGroupDir);
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
flushMicrotasks();
|
flushMicrotasks();
|
||||||
|
|
||||||
expect(formModel.find(["person", "login"])).not.toBeNull;
|
expect(formModel.find(['person', 'login'])).not.toBeNull;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// should update the form's value and validity
|
// should update the form's value and validity
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("removeControl & removeControlGroup", () => {
|
describe('removeControl & removeControlGroup', () => {
|
||||||
it("should remove control", fakeAsync(() => {
|
it('should remove control', fakeAsync(() => {
|
||||||
form.addControlGroup(personControlGroupDir);
|
form.addControlGroup(personControlGroupDir);
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
|
@ -340,45 +313,45 @@ export function main() {
|
||||||
|
|
||||||
flushMicrotasks();
|
flushMicrotasks();
|
||||||
|
|
||||||
expect(formModel.find(["person"])).toBeNull();
|
expect(formModel.find(['person'])).toBeNull();
|
||||||
expect(formModel.find(["person", "login"])).toBeNull();
|
expect(formModel.find(['person', 'login'])).toBeNull();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// should update the form's value and validity
|
// should update the form's value and validity
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up sync validator", fakeAsync(() => {
|
it('should set up sync validator', fakeAsync(() => {
|
||||||
var formValidator = (c: any /** TODO #9100 */) => ({"custom": true});
|
var formValidator = (c: any /** TODO #9100 */) => ({'custom': true});
|
||||||
var f = new NgForm([formValidator], []);
|
var f = new NgForm([formValidator], []);
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(f.form.errors).toEqual({"custom": true});
|
expect(f.form.errors).toEqual({'custom': true});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should set up async validator", fakeAsync(() => {
|
it('should set up async validator', fakeAsync(() => {
|
||||||
var f = new NgForm([], [asyncValidator("expected")]);
|
var f = new NgForm([], [asyncValidator('expected')]);
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(f.form.errors).toEqual({"async": true});
|
expect(f.form.errors).toEqual({'async': true});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgControlGroup", () => {
|
describe('NgControlGroup', () => {
|
||||||
var formModel: any /** TODO #9100 */;
|
var formModel: any /** TODO #9100 */;
|
||||||
var controlGroupDir: any /** TODO #9100 */;
|
var controlGroupDir: any /** TODO #9100 */;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
formModel = new ControlGroup({"login": new Control(null)});
|
formModel = new ControlGroup({'login': new Control(null)});
|
||||||
|
|
||||||
var parent = new NgFormModel([], []);
|
var parent = new NgFormModel([], []);
|
||||||
parent.form = new ControlGroup({"group": formModel});
|
parent.form = new ControlGroup({'group': formModel});
|
||||||
controlGroupDir = new NgControlGroup(parent, [], []);
|
controlGroupDir = new NgControlGroup(parent, [], []);
|
||||||
controlGroupDir.name = "group";
|
controlGroupDir.name = 'group';
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
expect(controlGroupDir.control).toBe(formModel);
|
expect(controlGroupDir.control).toBe(formModel);
|
||||||
expect(controlGroupDir.value).toBe(formModel.value);
|
expect(controlGroupDir.value).toBe(formModel.value);
|
||||||
expect(controlGroupDir.valid).toBe(formModel.valid);
|
expect(controlGroupDir.valid).toBe(formModel.valid);
|
||||||
|
@ -390,7 +363,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgFormControl", () => {
|
describe('NgFormControl', () => {
|
||||||
var controlDir: any /** TODO #9100 */;
|
var controlDir: any /** TODO #9100 */;
|
||||||
var control: any /** TODO #9100 */;
|
var control: any /** TODO #9100 */;
|
||||||
var checkProperties = function(control: any /** TODO #9100 */) {
|
var checkProperties = function(control: any /** TODO #9100 */) {
|
||||||
|
@ -412,36 +385,36 @@ export function main() {
|
||||||
controlDir.form = control;
|
controlDir.form = control;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => { checkProperties(control); });
|
it('should reexport control properties', () => { checkProperties(control); });
|
||||||
|
|
||||||
it("should reexport new control properties", () => {
|
it('should reexport new control properties', () => {
|
||||||
var newControl = new Control(null);
|
var newControl = new Control(null);
|
||||||
controlDir.form = newControl;
|
controlDir.form = newControl;
|
||||||
controlDir.ngOnChanges({"form": new SimpleChange(control, newControl)});
|
controlDir.ngOnChanges({'form': new SimpleChange(control, newControl)});
|
||||||
|
|
||||||
checkProperties(newControl);
|
checkProperties(newControl);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validator", () => {
|
it('should set up validator', () => {
|
||||||
expect(control.valid).toBe(true);
|
expect(control.valid).toBe(true);
|
||||||
|
|
||||||
// this will add the required validator and recalculate the validity
|
// this will add the required validator and recalculate the validity
|
||||||
controlDir.ngOnChanges({"form": new SimpleChange(null, control)});
|
controlDir.ngOnChanges({'form': new SimpleChange(null, control)});
|
||||||
|
|
||||||
expect(control.valid).toBe(false);
|
expect(control.valid).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgModel", () => {
|
describe('NgModel', () => {
|
||||||
var ngModel: any /** TODO #9100 */;
|
var ngModel: any /** TODO #9100 */;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ngModel =
|
ngModel =
|
||||||
new NgModel([Validators.required], [asyncValidator("expected")], [defaultAccessor]);
|
new NgModel([Validators.required], [asyncValidator('expected')], [defaultAccessor]);
|
||||||
ngModel.valueAccessor = new DummyControlValueAccessor();
|
ngModel.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
var control = ngModel.control;
|
var control = ngModel.control;
|
||||||
expect(ngModel.control).toBe(control);
|
expect(ngModel.control).toBe(control);
|
||||||
expect(ngModel.value).toBe(control.value);
|
expect(ngModel.value).toBe(control.value);
|
||||||
|
@ -453,34 +426,34 @@ export function main() {
|
||||||
expect(ngModel.untouched).toBe(control.untouched);
|
expect(ngModel.untouched).toBe(control.untouched);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validator", fakeAsync(() => {
|
it('should set up validator', fakeAsync(() => {
|
||||||
// this will add the required validator and recalculate the validity
|
// this will add the required validator and recalculate the validity
|
||||||
ngModel.ngOnChanges({});
|
ngModel.ngOnChanges({});
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(ngModel.control.errors).toEqual({"required": true});
|
expect(ngModel.control.errors).toEqual({'required': true});
|
||||||
|
|
||||||
ngModel.control.updateValue("someValue");
|
ngModel.control.updateValue('someValue');
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(ngModel.control.errors).toEqual({"async": true});
|
expect(ngModel.control.errors).toEqual({'async': true});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgControlName", () => {
|
describe('NgControlName', () => {
|
||||||
var formModel: any /** TODO #9100 */;
|
var formModel: any /** TODO #9100 */;
|
||||||
var controlNameDir: any /** TODO #9100 */;
|
var controlNameDir: any /** TODO #9100 */;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
formModel = new Control("name");
|
formModel = new Control('name');
|
||||||
|
|
||||||
var parent = new NgFormModel([], []);
|
var parent = new NgFormModel([], []);
|
||||||
parent.form = new ControlGroup({"name": formModel});
|
parent.form = new ControlGroup({'name': formModel});
|
||||||
controlNameDir = new NgControlName(parent, [], [], [defaultAccessor]);
|
controlNameDir = new NgControlName(parent, [], [], [defaultAccessor]);
|
||||||
controlNameDir.name = "name";
|
controlNameDir.name = 'name';
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
expect(controlNameDir.control).toBe(formModel);
|
expect(controlNameDir.control).toBe(formModel);
|
||||||
expect(controlNameDir.value).toBe(formModel.value);
|
expect(controlNameDir.value).toBe(formModel.value);
|
||||||
expect(controlNameDir.valid).toBe(formModel.valid);
|
expect(controlNameDir.valid).toBe(formModel.valid);
|
||||||
|
|
|
@ -1,67 +1,59 @@
|
||||||
import {
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {Control, FormBuilder} from '@angular/common';
|
import {Control, FormBuilder} from '@angular/common';
|
||||||
|
import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
|
|
||||||
import {PromiseWrapper} from '../../src/facade/promise';
|
import {PromiseWrapper} from '../../src/facade/promise';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
function syncValidator(_: any /** TODO #9100 */): any /** TODO #9100 */ { return null; }
|
function syncValidator(_: any /** TODO #9100 */): any /** TODO #9100 */ { return null; }
|
||||||
function asyncValidator(_: any /** TODO #9100 */) { return PromiseWrapper.resolve(null); }
|
function asyncValidator(_: any /** TODO #9100 */) { return PromiseWrapper.resolve(null); }
|
||||||
|
|
||||||
describe("Form Builder", () => {
|
describe('Form Builder', () => {
|
||||||
var b: any /** TODO #9100 */;
|
var b: any /** TODO #9100 */;
|
||||||
|
|
||||||
beforeEach(() => { b = new FormBuilder(); });
|
beforeEach(() => { b = new FormBuilder(); });
|
||||||
|
|
||||||
it("should create controls from a value", () => {
|
it('should create controls from a value', () => {
|
||||||
var g = b.group({"login": "some value"});
|
var g = b.group({'login': 'some value'});
|
||||||
|
|
||||||
expect(g.controls["login"].value).toEqual("some value");
|
expect(g.controls['login'].value).toEqual('some value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create controls from an array", () => {
|
it('should create controls from an array', () => {
|
||||||
var g = b.group(
|
var g = b.group(
|
||||||
{"login": ["some value"], "password": ["some value", syncValidator, asyncValidator]});
|
{'login': ['some value'], 'password': ['some value', syncValidator, asyncValidator]});
|
||||||
|
|
||||||
expect(g.controls["login"].value).toEqual("some value");
|
expect(g.controls['login'].value).toEqual('some value');
|
||||||
expect(g.controls["password"].value).toEqual("some value");
|
expect(g.controls['password'].value).toEqual('some value');
|
||||||
expect(g.controls["password"].validator).toEqual(syncValidator);
|
expect(g.controls['password'].validator).toEqual(syncValidator);
|
||||||
expect(g.controls["password"].asyncValidator).toEqual(asyncValidator);
|
expect(g.controls['password'].asyncValidator).toEqual(asyncValidator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should use controls", () => {
|
it('should use controls', () => {
|
||||||
var g = b.group({"login": b.control("some value", syncValidator, asyncValidator)});
|
var g = b.group({'login': b.control('some value', syncValidator, asyncValidator)});
|
||||||
|
|
||||||
expect(g.controls["login"].value).toEqual("some value");
|
expect(g.controls['login'].value).toEqual('some value');
|
||||||
expect(g.controls["login"].validator).toBe(syncValidator);
|
expect(g.controls['login'].validator).toBe(syncValidator);
|
||||||
expect(g.controls["login"].asyncValidator).toBe(asyncValidator);
|
expect(g.controls['login'].asyncValidator).toBe(asyncValidator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create groups with optional controls", () => {
|
it('should create groups with optional controls', () => {
|
||||||
var g = b.group({"login": "some value"}, {"optionals": {"login": false}});
|
var g = b.group({'login': 'some value'}, {'optionals': {'login': false}});
|
||||||
|
|
||||||
expect(g.contains("login")).toEqual(false);
|
expect(g.contains('login')).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create groups with a custom validator", () => {
|
it('should create groups with a custom validator', () => {
|
||||||
var g = b.group({"login": "some value"},
|
var g = b.group(
|
||||||
{"validator": syncValidator, "asyncValidator": asyncValidator});
|
{'login': 'some value'}, {'validator': syncValidator, 'asyncValidator': asyncValidator});
|
||||||
|
|
||||||
expect(g.validator).toBe(syncValidator);
|
expect(g.validator).toBe(syncValidator);
|
||||||
expect(g.asyncValidator).toBe(asyncValidator);
|
expect(g.asyncValidator).toBe(asyncValidator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create control arrays", () => {
|
it('should create control arrays', () => {
|
||||||
var c = b.control("three");
|
var c = b.control('three');
|
||||||
var a = b.array(["one", ["two", syncValidator], c, b.array(['four'])], syncValidator,
|
var a = b.array(
|
||||||
asyncValidator);
|
['one', ['two', syncValidator], c, b.array(['four'])], syncValidator, asyncValidator);
|
||||||
|
|
||||||
expect(a.value).toEqual(['one', 'two', 'three', ['four']]);
|
expect(a.value).toEqual(['one', 'two', 'three', ['four']]);
|
||||||
expect(a.validator).toBe(syncValidator);
|
expect(a.validator).toBe(syncValidator);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,9 @@
|
||||||
import {
|
import {AbstractControl, Control, ControlArray, ControlGroup, Validators} from '@angular/common';
|
||||||
ddescribe,
|
import {Log, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
|
||||||
describe,
|
import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {fakeAsync, flushMicrotasks, Log, tick} from '@angular/core/testing';
|
|
||||||
import {ControlGroup, Control, Validators, AbstractControl, ControlArray} from '@angular/common';
|
|
||||||
import {PromiseWrapper} from '../../src/facade/promise';
|
|
||||||
import {EventEmitter, ObservableWrapper, TimerWrapper} from '../../src/facade/async';
|
import {EventEmitter, ObservableWrapper, TimerWrapper} from '../../src/facade/async';
|
||||||
|
import {PromiseWrapper} from '../../src/facade/promise';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
function validator(key: string, error: any) {
|
function validator(key: string, error: any) {
|
||||||
|
@ -22,95 +14,98 @@ export function main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("Validators", () => {
|
describe('Validators', () => {
|
||||||
describe("required", () => {
|
describe('required', () => {
|
||||||
it("should error on an empty string",
|
it('should error on an empty string',
|
||||||
() => { expect(Validators.required(new Control(""))).toEqual({"required": true}); });
|
() => { expect(Validators.required(new Control(''))).toEqual({'required': true}); });
|
||||||
|
|
||||||
it("should error on null",
|
it('should error on null',
|
||||||
() => { expect(Validators.required(new Control(null))).toEqual({"required": true}); });
|
() => { expect(Validators.required(new Control(null))).toEqual({'required': true}); });
|
||||||
|
|
||||||
it("should not error on a non-empty string",
|
it('should not error on a non-empty string',
|
||||||
() => { expect(Validators.required(new Control("not empty"))).toEqual(null); });
|
() => { expect(Validators.required(new Control('not empty'))).toEqual(null); });
|
||||||
|
|
||||||
it("should accept zero as valid",
|
it('should accept zero as valid',
|
||||||
() => { expect(Validators.required(new Control(0))).toEqual(null); });
|
() => { expect(Validators.required(new Control(0))).toEqual(null); });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("minLength", () => {
|
describe('minLength', () => {
|
||||||
it("should not error on an empty string",
|
it('should not error on an empty string',
|
||||||
() => { expect(Validators.minLength(2)(new Control(""))).toEqual(null); });
|
() => { expect(Validators.minLength(2)(new Control(''))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on null",
|
it('should not error on null',
|
||||||
() => { expect(Validators.minLength(2)(new Control(null))).toEqual(null); });
|
() => { expect(Validators.minLength(2)(new Control(null))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on valid strings",
|
it('should not error on valid strings',
|
||||||
() => { expect(Validators.minLength(2)(new Control("aa"))).toEqual(null); });
|
() => { expect(Validators.minLength(2)(new Control('aa'))).toEqual(null); });
|
||||||
|
|
||||||
it("should error on short strings", () => {
|
it('should error on short strings', () => {
|
||||||
expect(Validators.minLength(2)(new Control("a")))
|
expect(Validators.minLength(2)(new Control('a'))).toEqual({
|
||||||
.toEqual({"minlength": {"requiredLength": 2, "actualLength": 1}});
|
'minlength': {'requiredLength': 2, 'actualLength': 1}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("maxLength", () => {
|
describe('maxLength', () => {
|
||||||
it("should not error on an empty string",
|
it('should not error on an empty string',
|
||||||
() => { expect(Validators.maxLength(2)(new Control(""))).toEqual(null); });
|
() => { expect(Validators.maxLength(2)(new Control(''))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on null",
|
it('should not error on null',
|
||||||
() => { expect(Validators.maxLength(2)(new Control(null))).toEqual(null); });
|
() => { expect(Validators.maxLength(2)(new Control(null))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on valid strings",
|
it('should not error on valid strings',
|
||||||
() => { expect(Validators.maxLength(2)(new Control("aa"))).toEqual(null); });
|
() => { expect(Validators.maxLength(2)(new Control('aa'))).toEqual(null); });
|
||||||
|
|
||||||
it("should error on long strings", () => {
|
it('should error on long strings', () => {
|
||||||
expect(Validators.maxLength(2)(new Control("aaa")))
|
expect(Validators.maxLength(2)(new Control('aaa'))).toEqual({
|
||||||
.toEqual({"maxlength": {"requiredLength": 2, "actualLength": 3}});
|
'maxlength': {'requiredLength': 2, 'actualLength': 3}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("pattern", () => {
|
describe('pattern', () => {
|
||||||
it("should not error on an empty string",
|
it('should not error on an empty string',
|
||||||
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control(""))).toEqual(null); });
|
() => { expect(Validators.pattern('[a-zA-Z ]*')(new Control(''))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on null",
|
it('should not error on null',
|
||||||
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control(null))).toEqual(null); });
|
() => { expect(Validators.pattern('[a-zA-Z ]*')(new Control(null))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on valid strings",
|
it('should not error on valid strings',
|
||||||
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control("aaAA"))).toEqual(null); });
|
() => { expect(Validators.pattern('[a-zA-Z ]*')(new Control('aaAA'))).toEqual(null); });
|
||||||
|
|
||||||
it("should error on failure to match string", () => {
|
it('should error on failure to match string', () => {
|
||||||
expect(Validators.pattern("[a-zA-Z ]*")(new Control("aaa0")))
|
expect(Validators.pattern('[a-zA-Z ]*')(new Control('aaa0'))).toEqual({
|
||||||
.toEqual({"pattern": {"requiredPattern": "^[a-zA-Z ]*$", "actualValue": "aaa0"}});
|
'pattern': {'requiredPattern': '^[a-zA-Z ]*$', 'actualValue': 'aaa0'}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("compose", () => {
|
describe('compose', () => {
|
||||||
it("should return null when given null",
|
it('should return null when given null',
|
||||||
() => { expect(Validators.compose(null)).toBe(null); });
|
() => { expect(Validators.compose(null)).toBe(null); });
|
||||||
|
|
||||||
it("should collect errors from all the validators", () => {
|
it('should collect errors from all the validators', () => {
|
||||||
var c = Validators.compose([validator("a", true), validator("b", true)]);
|
var c = Validators.compose([validator('a', true), validator('b', true)]);
|
||||||
expect(c(new Control(""))).toEqual({"a": true, "b": true});
|
expect(c(new Control(''))).toEqual({'a': true, 'b': true});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should run validators left to right", () => {
|
it('should run validators left to right', () => {
|
||||||
var c = Validators.compose([validator("a", 1), validator("a", 2)]);
|
var c = Validators.compose([validator('a', 1), validator('a', 2)]);
|
||||||
expect(c(new Control(""))).toEqual({"a": 2});
|
expect(c(new Control(''))).toEqual({'a': 2});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return null when no errors", () => {
|
it('should return null when no errors', () => {
|
||||||
var c = Validators.compose([Validators.nullValidator, Validators.nullValidator]);
|
var c = Validators.compose([Validators.nullValidator, Validators.nullValidator]);
|
||||||
expect(c(new Control(""))).toEqual(null);
|
expect(c(new Control(''))).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should ignore nulls", () => {
|
it('should ignore nulls', () => {
|
||||||
var c = Validators.compose([null, Validators.required]);
|
var c = Validators.compose([null, Validators.required]);
|
||||||
expect(c(new Control(""))).toEqual({"required": true});
|
expect(c(new Control(''))).toEqual({'required': true});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("composeAsync", () => {
|
describe('composeAsync', () => {
|
||||||
function asyncValidator(expected: any /** TODO #9100 */, response: any /** TODO #9100 */) {
|
function asyncValidator(expected: any /** TODO #9100 */, response: any /** TODO #9100 */) {
|
||||||
return (c: any /** TODO #9100 */) => {
|
return (c: any /** TODO #9100 */) => {
|
||||||
var emitter = new EventEmitter();
|
var emitter = new EventEmitter();
|
||||||
|
@ -127,43 +122,42 @@ export function main() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should return null when given null",
|
it('should return null when given null',
|
||||||
() => { expect(Validators.composeAsync(null)).toEqual(null); });
|
() => { expect(Validators.composeAsync(null)).toEqual(null); });
|
||||||
|
|
||||||
it("should collect errors from all the validators", fakeAsync(() => {
|
it('should collect errors from all the validators', fakeAsync(() => {
|
||||||
var c = Validators.composeAsync([
|
var c = Validators.composeAsync([
|
||||||
asyncValidator("expected", {"one": true}),
|
asyncValidator('expected', {'one': true}), asyncValidator('expected', {'two': true})
|
||||||
asyncValidator("expected", {"two": true})
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var value: any /** TODO #9100 */ = null;
|
var value: any /** TODO #9100 */ = null;
|
||||||
(<Promise<any>>c(new Control("invalid"))).then(v => value = v);
|
(<Promise<any>>c(new Control('invalid'))).then(v => value = v);
|
||||||
|
|
||||||
tick(1);
|
tick(1);
|
||||||
|
|
||||||
expect(value).toEqual({"one": true, "two": true});
|
expect(value).toEqual({'one': true, 'two': true});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should return null when no errors", fakeAsync(() => {
|
it('should return null when no errors', fakeAsync(() => {
|
||||||
var c = Validators.composeAsync([asyncValidator("expected", {"one": true})]);
|
var c = Validators.composeAsync([asyncValidator('expected', {'one': true})]);
|
||||||
|
|
||||||
var value: any /** TODO #9100 */ = null;
|
var value: any /** TODO #9100 */ = null;
|
||||||
(<Promise<any>>c(new Control("expected"))).then(v => value = v);
|
(<Promise<any>>c(new Control('expected'))).then(v => value = v);
|
||||||
|
|
||||||
tick(1);
|
tick(1);
|
||||||
|
|
||||||
expect(value).toEqual(null);
|
expect(value).toEqual(null);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should ignore nulls", fakeAsync(() => {
|
it('should ignore nulls', fakeAsync(() => {
|
||||||
var c = Validators.composeAsync([asyncValidator("expected", {"one": true}), null]);
|
var c = Validators.composeAsync([asyncValidator('expected', {'one': true}), null]);
|
||||||
|
|
||||||
var value: any /** TODO #9100 */ = null;
|
var value: any /** TODO #9100 */ = null;
|
||||||
(<Promise<any>>c(new Control("invalid"))).then(v => value = v);
|
(<Promise<any>>c(new Control('invalid'))).then(v => value = v);
|
||||||
|
|
||||||
tick(1);
|
tick(1);
|
||||||
|
|
||||||
expect(value).toEqual({"one": true});
|
expect(value).toEqual({'one': true});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,41 +1,10 @@
|
||||||
import {
|
import {afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach,
|
|
||||||
inject
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
|
|
||||||
import {
|
import {fakeAsync, flushMicrotasks, Log, tick,} from '@angular/core/testing';
|
||||||
fakeAsync,
|
|
||||||
flushMicrotasks,
|
|
||||||
Log,
|
|
||||||
tick,
|
|
||||||
} from '@angular/core/testing';
|
|
||||||
|
|
||||||
import {SpyNgControl, SpyValueAccessor} from '../spies';
|
import {SpyNgControl, SpyValueAccessor} from '../spies';
|
||||||
|
|
||||||
import {
|
import {ControlGroup, Control, NgControlName, NgControlGroup, NgFormModel, ControlValueAccessor, Validators, NgForm, NgModel, NgFormControl, NgControl, DefaultValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, Validator} from '@angular/common/src/forms';
|
||||||
ControlGroup,
|
|
||||||
Control,
|
|
||||||
NgControlName,
|
|
||||||
NgControlGroup,
|
|
||||||
NgFormModel,
|
|
||||||
ControlValueAccessor,
|
|
||||||
Validators,
|
|
||||||
NgForm,
|
|
||||||
NgModel,
|
|
||||||
NgFormControl,
|
|
||||||
NgControl,
|
|
||||||
DefaultValueAccessor,
|
|
||||||
CheckboxControlValueAccessor,
|
|
||||||
SelectControlValueAccessor,
|
|
||||||
Validator
|
|
||||||
} from '@angular/common/src/forms';
|
|
||||||
|
|
||||||
|
|
||||||
import {selectValueAccessor, composeValidators} from '@angular/common/src/forms/directives/shared';
|
import {selectValueAccessor, composeValidators} from '@angular/common/src/forms/directives/shared';
|
||||||
|
@ -53,13 +22,13 @@ class DummyControlValueAccessor implements ControlValueAccessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomValidatorDirective implements Validator {
|
class CustomValidatorDirective implements Validator {
|
||||||
validate(c: Control): {[key: string]: any} { return {"custom": true}; }
|
validate(c: Control): {[key: string]: any} { return {'custom': true}; }
|
||||||
}
|
}
|
||||||
|
|
||||||
function asyncValidator(expected: any /** TODO #9100 */, timeout = 0) {
|
function asyncValidator(expected: any /** TODO #9100 */, timeout = 0) {
|
||||||
return (c: any /** TODO #9100 */) => {
|
return (c: any /** TODO #9100 */) => {
|
||||||
var completer = PromiseWrapper.completer();
|
var completer = PromiseWrapper.completer();
|
||||||
var res = c.value != expected ? {"async": true} : null;
|
var res = c.value != expected ? {'async': true} : null;
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
completer.resolve(res);
|
completer.resolve(res);
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,71 +39,73 @@ function asyncValidator(expected: any /** TODO #9100 */, timeout = 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe("Form Directives", () => {
|
describe('Form Directives', () => {
|
||||||
var defaultAccessor: DefaultValueAccessor;
|
var defaultAccessor: DefaultValueAccessor;
|
||||||
|
|
||||||
beforeEach(() => { defaultAccessor = new DefaultValueAccessor(null, null); });
|
beforeEach(() => { defaultAccessor = new DefaultValueAccessor(null, null); });
|
||||||
|
|
||||||
describe("shared", () => {
|
describe('shared', () => {
|
||||||
describe("selectValueAccessor", () => {
|
describe('selectValueAccessor', () => {
|
||||||
var dir: NgControl;
|
var dir: NgControl;
|
||||||
|
|
||||||
beforeEach(() => { dir = <any>new SpyNgControl(); });
|
beforeEach(() => { dir = <any>new SpyNgControl(); });
|
||||||
|
|
||||||
it("should throw when given an empty array",
|
it('should throw when given an empty array',
|
||||||
() => { expect(() => selectValueAccessor(dir, [])).toThrowError(); });
|
() => { expect(() => selectValueAccessor(dir, [])).toThrowError(); });
|
||||||
|
|
||||||
it("should return the default value accessor when no other provided",
|
it('should return the default value accessor when no other provided',
|
||||||
() => { expect(selectValueAccessor(dir, [defaultAccessor])).toEqual(defaultAccessor); });
|
() => { expect(selectValueAccessor(dir, [defaultAccessor])).toEqual(defaultAccessor); });
|
||||||
|
|
||||||
it("should return checkbox accessor when provided", () => {
|
it('should return checkbox accessor when provided', () => {
|
||||||
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
||||||
expect(selectValueAccessor(dir, [defaultAccessor, checkboxAccessor]))
|
expect(selectValueAccessor(dir, [
|
||||||
.toEqual(checkboxAccessor);
|
defaultAccessor, checkboxAccessor
|
||||||
|
])).toEqual(checkboxAccessor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return select accessor when provided", () => {
|
it('should return select accessor when provided', () => {
|
||||||
var selectAccessor = new SelectControlValueAccessor(null, null);
|
var selectAccessor = new SelectControlValueAccessor(null, null);
|
||||||
expect(selectValueAccessor(dir, [defaultAccessor, selectAccessor]))
|
expect(selectValueAccessor(dir, [
|
||||||
.toEqual(selectAccessor);
|
defaultAccessor, selectAccessor
|
||||||
|
])).toEqual(selectAccessor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when more than one build-in accessor is provided", () => {
|
it('should throw when more than one build-in accessor is provided', () => {
|
||||||
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
||||||
var selectAccessor = new SelectControlValueAccessor(null, null);
|
var selectAccessor = new SelectControlValueAccessor(null, null);
|
||||||
expect(() => selectValueAccessor(dir, [checkboxAccessor, selectAccessor])).toThrowError();
|
expect(() => selectValueAccessor(dir, [checkboxAccessor, selectAccessor])).toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return custom accessor when provided", () => {
|
it('should return custom accessor when provided', () => {
|
||||||
var customAccessor = new SpyValueAccessor();
|
var customAccessor = new SpyValueAccessor();
|
||||||
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
var checkboxAccessor = new CheckboxControlValueAccessor(null, null);
|
||||||
expect(selectValueAccessor(dir, <any>[defaultAccessor, customAccessor, checkboxAccessor]))
|
expect(selectValueAccessor(dir, <any>[defaultAccessor, customAccessor, checkboxAccessor]))
|
||||||
.toEqual(customAccessor);
|
.toEqual(customAccessor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when more than one custom accessor is provided", () => {
|
it('should throw when more than one custom accessor is provided', () => {
|
||||||
var customAccessor: ControlValueAccessor = <any>new SpyValueAccessor();
|
var customAccessor: ControlValueAccessor = <any>new SpyValueAccessor();
|
||||||
expect(() => selectValueAccessor(dir, [customAccessor, customAccessor])).toThrowError();
|
expect(() => selectValueAccessor(dir, [customAccessor, customAccessor])).toThrowError();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("composeValidators", () => {
|
describe('composeValidators', () => {
|
||||||
it("should compose functions", () => {
|
it('should compose functions', () => {
|
||||||
var dummy1 = (_: any /** TODO #9100 */) => ({"dummy1": true});
|
var dummy1 = (_: any /** TODO #9100 */) => ({'dummy1': true});
|
||||||
var dummy2 = (_: any /** TODO #9100 */) => ({"dummy2": true});
|
var dummy2 = (_: any /** TODO #9100 */) => ({'dummy2': true});
|
||||||
var v = composeValidators([dummy1, dummy2]);
|
var v = composeValidators([dummy1, dummy2]);
|
||||||
expect(v(new Control(""))).toEqual({"dummy1": true, "dummy2": true});
|
expect(v(new Control(''))).toEqual({'dummy1': true, 'dummy2': true});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should compose validator directives", () => {
|
it('should compose validator directives', () => {
|
||||||
var dummy1 = (_: any /** TODO #9100 */) => ({"dummy1": true});
|
var dummy1 = (_: any /** TODO #9100 */) => ({'dummy1': true});
|
||||||
var v = composeValidators([dummy1, new CustomValidatorDirective()]);
|
var v = composeValidators([dummy1, new CustomValidatorDirective()]);
|
||||||
expect(v(new Control(""))).toEqual({"dummy1": true, "custom": true});
|
expect(v(new Control(''))).toEqual({'dummy1': true, 'custom': true});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgFormModel", () => {
|
describe('NgFormModel', () => {
|
||||||
var form: any /** TODO #9100 */;
|
var form: any /** TODO #9100 */;
|
||||||
var formModel: ControlGroup;
|
var formModel: ControlGroup;
|
||||||
var loginControlDir: any /** TODO #9100 */;
|
var loginControlDir: any /** TODO #9100 */;
|
||||||
|
@ -142,19 +113,19 @@ export function main() {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
form = new NgFormModel([], []);
|
form = new NgFormModel([], []);
|
||||||
formModel = new ControlGroup({
|
formModel = new ControlGroup({
|
||||||
"login": new Control(),
|
'login': new Control(),
|
||||||
"passwords":
|
'passwords':
|
||||||
new ControlGroup({"password": new Control(), "passwordConfirm": new Control()})
|
new ControlGroup({'password': new Control(), 'passwordConfirm': new Control()})
|
||||||
});
|
});
|
||||||
form.form = formModel;
|
form.form = formModel;
|
||||||
|
|
||||||
loginControlDir = new NgControlName(form, [Validators.required],
|
loginControlDir = new NgControlName(
|
||||||
[asyncValidator("expected")], [defaultAccessor]);
|
form, [Validators.required], [asyncValidator('expected')], [defaultAccessor]);
|
||||||
loginControlDir.name = "login";
|
loginControlDir.name = 'login';
|
||||||
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
expect(form.control).toBe(formModel);
|
expect(form.control).toBe(formModel);
|
||||||
expect(form.value).toBe(formModel.value);
|
expect(form.value).toBe(formModel.value);
|
||||||
expect(form.valid).toBe(formModel.valid);
|
expect(form.valid).toBe(formModel.valid);
|
||||||
|
@ -165,130 +136,132 @@ export function main() {
|
||||||
expect(form.untouched).toBe(formModel.untouched);
|
expect(form.untouched).toBe(formModel.untouched);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("addControl", () => {
|
describe('addControl', () => {
|
||||||
it("should throw when no control found", () => {
|
it('should throw when no control found', () => {
|
||||||
var dir = new NgControlName(form, null, null, [defaultAccessor]);
|
var dir = new NgControlName(form, null, null, [defaultAccessor]);
|
||||||
dir.name = "invalidName";
|
dir.name = 'invalidName';
|
||||||
|
|
||||||
expect(() => form.addControl(dir))
|
expect(() => form.addControl(dir))
|
||||||
.toThrowError(new RegExp("Cannot find control 'invalidName'"));
|
.toThrowError(new RegExp('Cannot find control \'invalidName\''));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when no value accessor", () => {
|
it('should throw when no value accessor', () => {
|
||||||
var dir = new NgControlName(form, null, null, null);
|
var dir = new NgControlName(form, null, null, null);
|
||||||
dir.name = "login";
|
dir.name = 'login';
|
||||||
|
|
||||||
expect(() => form.addControl(dir))
|
expect(() => form.addControl(dir))
|
||||||
.toThrowError(new RegExp("No value accessor for 'login'"));
|
.toThrowError(new RegExp('No value accessor for \'login\''));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validators", fakeAsync(() => {
|
it('should set up validators', fakeAsync(() => {
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
// sync validators are set
|
// sync validators are set
|
||||||
expect(formModel.hasError("required", ["login"])).toBe(true);
|
expect(formModel.hasError('required', ['login'])).toBe(true);
|
||||||
expect(formModel.hasError("async", ["login"])).toBe(false);
|
expect(formModel.hasError('async', ['login'])).toBe(false);
|
||||||
|
|
||||||
(<Control>formModel.find(["login"])).updateValue("invalid value");
|
(<Control>formModel.find(['login'])).updateValue('invalid value');
|
||||||
|
|
||||||
// sync validator passes, running async validators
|
// sync validator passes, running async validators
|
||||||
expect(formModel.pending).toBe(true);
|
expect(formModel.pending).toBe(true);
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(formModel.hasError("required", ["login"])).toBe(false);
|
expect(formModel.hasError('required', ['login'])).toBe(false);
|
||||||
expect(formModel.hasError("async", ["login"])).toBe(true);
|
expect(formModel.hasError('async', ['login'])).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should write value to the DOM", () => {
|
it('should write value to the DOM', () => {
|
||||||
(<Control>formModel.find(["login"])).updateValue("initValue");
|
(<Control>formModel.find(['login'])).updateValue('initValue');
|
||||||
|
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual("initValue");
|
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual('initValue');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should add the directive to the list of directives included in the form", () => {
|
it('should add the directive to the list of directives included in the form', () => {
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
expect(form.directives).toEqual([loginControlDir]);
|
expect(form.directives).toEqual([loginControlDir]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("addControlGroup", () => {
|
describe('addControlGroup', () => {
|
||||||
var matchingPasswordsValidator = (g: any /** TODO #9100 */) => {
|
var matchingPasswordsValidator = (g: any /** TODO #9100 */) => {
|
||||||
if (g.controls["password"].value != g.controls["passwordConfirm"].value) {
|
if (g.controls['password'].value != g.controls['passwordConfirm'].value) {
|
||||||
return {"differentPasswords": true};
|
return {'differentPasswords': true};
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
it("should set up validator", fakeAsync(() => {
|
it('should set up validator', fakeAsync(() => {
|
||||||
var group = new NgControlGroup(form, [matchingPasswordsValidator],
|
var group = new NgControlGroup(
|
||||||
[asyncValidator('expected')]);
|
form, [matchingPasswordsValidator], [asyncValidator('expected')]);
|
||||||
group.name = "passwords";
|
group.name = 'passwords';
|
||||||
form.addControlGroup(group);
|
form.addControlGroup(group);
|
||||||
|
|
||||||
(<Control>formModel.find(["passwords", "password"])).updateValue("somePassword");
|
(<Control>formModel.find(['passwords', 'password'])).updateValue('somePassword');
|
||||||
(<Control>formModel.find(["passwords", "passwordConfirm"]))
|
(<Control>formModel.find([
|
||||||
.updateValue("someOtherPassword");
|
'passwords', 'passwordConfirm'
|
||||||
|
])).updateValue('someOtherPassword');
|
||||||
|
|
||||||
// sync validators are set
|
// sync validators are set
|
||||||
expect(formModel.hasError("differentPasswords", ["passwords"])).toEqual(true);
|
expect(formModel.hasError('differentPasswords', ['passwords'])).toEqual(true);
|
||||||
|
|
||||||
(<Control>formModel.find(["passwords", "passwordConfirm"]))
|
(<Control>formModel.find([
|
||||||
.updateValue("somePassword");
|
'passwords', 'passwordConfirm'
|
||||||
|
])).updateValue('somePassword');
|
||||||
|
|
||||||
// sync validators pass, running async validators
|
// sync validators pass, running async validators
|
||||||
expect(formModel.pending).toBe(true);
|
expect(formModel.pending).toBe(true);
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(formModel.hasError("async", ["passwords"])).toBe(true);
|
expect(formModel.hasError('async', ['passwords'])).toBe(true);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("removeControl", () => {
|
describe('removeControl', () => {
|
||||||
it("should remove the directive to the list of directives included in the form", () => {
|
it('should remove the directive to the list of directives included in the form', () => {
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
form.removeControl(loginControlDir);
|
form.removeControl(loginControlDir);
|
||||||
expect(form.directives).toEqual([]);
|
expect(form.directives).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("ngOnChanges", () => {
|
describe('ngOnChanges', () => {
|
||||||
it("should update dom values of all the directives", () => {
|
it('should update dom values of all the directives', () => {
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
(<Control>formModel.find(["login"])).updateValue("new value");
|
(<Control>formModel.find(['login'])).updateValue('new value');
|
||||||
|
|
||||||
form.ngOnChanges({});
|
form.ngOnChanges({});
|
||||||
|
|
||||||
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual("new value");
|
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual('new value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up a sync validator", () => {
|
it('should set up a sync validator', () => {
|
||||||
var formValidator = (c: any /** TODO #9100 */) => ({"custom": true});
|
var formValidator = (c: any /** TODO #9100 */) => ({'custom': true});
|
||||||
var f = new NgFormModel([formValidator], []);
|
var f = new NgFormModel([formValidator], []);
|
||||||
f.form = formModel;
|
f.form = formModel;
|
||||||
f.ngOnChanges({"form": new SimpleChange(null, null)});
|
f.ngOnChanges({'form': new SimpleChange(null, null)});
|
||||||
|
|
||||||
expect(formModel.errors).toEqual({"custom": true});
|
expect(formModel.errors).toEqual({'custom': true});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up an async validator", fakeAsync(() => {
|
it('should set up an async validator', fakeAsync(() => {
|
||||||
var f = new NgFormModel([], [asyncValidator("expected")]);
|
var f = new NgFormModel([], [asyncValidator('expected')]);
|
||||||
f.form = formModel;
|
f.form = formModel;
|
||||||
f.ngOnChanges({"form": new SimpleChange(null, null)});
|
f.ngOnChanges({'form': new SimpleChange(null, null)});
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(formModel.errors).toEqual({"async": true});
|
expect(formModel.errors).toEqual({'async': true});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgForm", () => {
|
describe('NgForm', () => {
|
||||||
var form: any /** TODO #9100 */;
|
var form: any /** TODO #9100 */;
|
||||||
var formModel: ControlGroup;
|
var formModel: ControlGroup;
|
||||||
var loginControlDir: any /** TODO #9100 */;
|
var loginControlDir: any /** TODO #9100 */;
|
||||||
|
@ -299,14 +272,14 @@ export function main() {
|
||||||
formModel = form.form;
|
formModel = form.form;
|
||||||
|
|
||||||
personControlGroupDir = new NgControlGroup(form, [], []);
|
personControlGroupDir = new NgControlGroup(form, [], []);
|
||||||
personControlGroupDir.name = "person";
|
personControlGroupDir.name = 'person';
|
||||||
|
|
||||||
loginControlDir = new NgControlName(personControlGroupDir, null, null, [defaultAccessor]);
|
loginControlDir = new NgControlName(personControlGroupDir, null, null, [defaultAccessor]);
|
||||||
loginControlDir.name = "login";
|
loginControlDir.name = 'login';
|
||||||
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
expect(form.control).toBe(formModel);
|
expect(form.control).toBe(formModel);
|
||||||
expect(form.value).toBe(formModel.value);
|
expect(form.value).toBe(formModel.value);
|
||||||
expect(form.valid).toBe(formModel.valid);
|
expect(form.valid).toBe(formModel.valid);
|
||||||
|
@ -317,21 +290,21 @@ export function main() {
|
||||||
expect(form.untouched).toBe(formModel.untouched);
|
expect(form.untouched).toBe(formModel.untouched);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("addControl & addControlGroup", () => {
|
describe('addControl & addControlGroup', () => {
|
||||||
it("should create a control with the given name", fakeAsync(() => {
|
it('should create a control with the given name', fakeAsync(() => {
|
||||||
form.addControlGroup(personControlGroupDir);
|
form.addControlGroup(personControlGroupDir);
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
flushMicrotasks();
|
flushMicrotasks();
|
||||||
|
|
||||||
expect(formModel.find(["person", "login"])).not.toBeNull;
|
expect(formModel.find(['person', 'login'])).not.toBeNull;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// should update the form's value and validity
|
// should update the form's value and validity
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("removeControl & removeControlGroup", () => {
|
describe('removeControl & removeControlGroup', () => {
|
||||||
it("should remove control", fakeAsync(() => {
|
it('should remove control', fakeAsync(() => {
|
||||||
form.addControlGroup(personControlGroupDir);
|
form.addControlGroup(personControlGroupDir);
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
|
@ -340,45 +313,45 @@ export function main() {
|
||||||
|
|
||||||
flushMicrotasks();
|
flushMicrotasks();
|
||||||
|
|
||||||
expect(formModel.find(["person"])).toBeNull();
|
expect(formModel.find(['person'])).toBeNull();
|
||||||
expect(formModel.find(["person", "login"])).toBeNull();
|
expect(formModel.find(['person', 'login'])).toBeNull();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// should update the form's value and validity
|
// should update the form's value and validity
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up sync validator", fakeAsync(() => {
|
it('should set up sync validator', fakeAsync(() => {
|
||||||
var formValidator = (c: any /** TODO #9100 */) => ({"custom": true});
|
var formValidator = (c: any /** TODO #9100 */) => ({'custom': true});
|
||||||
var f = new NgForm([formValidator], []);
|
var f = new NgForm([formValidator], []);
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(f.form.errors).toEqual({"custom": true});
|
expect(f.form.errors).toEqual({'custom': true});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should set up async validator", fakeAsync(() => {
|
it('should set up async validator', fakeAsync(() => {
|
||||||
var f = new NgForm([], [asyncValidator("expected")]);
|
var f = new NgForm([], [asyncValidator('expected')]);
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(f.form.errors).toEqual({"async": true});
|
expect(f.form.errors).toEqual({'async': true});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgControlGroup", () => {
|
describe('NgControlGroup', () => {
|
||||||
var formModel: any /** TODO #9100 */;
|
var formModel: any /** TODO #9100 */;
|
||||||
var controlGroupDir: any /** TODO #9100 */;
|
var controlGroupDir: any /** TODO #9100 */;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
formModel = new ControlGroup({"login": new Control(null)});
|
formModel = new ControlGroup({'login': new Control(null)});
|
||||||
|
|
||||||
var parent = new NgFormModel([], []);
|
var parent = new NgFormModel([], []);
|
||||||
parent.form = new ControlGroup({"group": formModel});
|
parent.form = new ControlGroup({'group': formModel});
|
||||||
controlGroupDir = new NgControlGroup(parent, [], []);
|
controlGroupDir = new NgControlGroup(parent, [], []);
|
||||||
controlGroupDir.name = "group";
|
controlGroupDir.name = 'group';
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
expect(controlGroupDir.control).toBe(formModel);
|
expect(controlGroupDir.control).toBe(formModel);
|
||||||
expect(controlGroupDir.value).toBe(formModel.value);
|
expect(controlGroupDir.value).toBe(formModel.value);
|
||||||
expect(controlGroupDir.valid).toBe(formModel.valid);
|
expect(controlGroupDir.valid).toBe(formModel.valid);
|
||||||
|
@ -390,7 +363,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgFormControl", () => {
|
describe('NgFormControl', () => {
|
||||||
var controlDir: any /** TODO #9100 */;
|
var controlDir: any /** TODO #9100 */;
|
||||||
var control: any /** TODO #9100 */;
|
var control: any /** TODO #9100 */;
|
||||||
var checkProperties = function(control: any /** TODO #9100 */) {
|
var checkProperties = function(control: any /** TODO #9100 */) {
|
||||||
|
@ -412,36 +385,36 @@ export function main() {
|
||||||
controlDir.form = control;
|
controlDir.form = control;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => { checkProperties(control); });
|
it('should reexport control properties', () => { checkProperties(control); });
|
||||||
|
|
||||||
it("should reexport new control properties", () => {
|
it('should reexport new control properties', () => {
|
||||||
var newControl = new Control(null);
|
var newControl = new Control(null);
|
||||||
controlDir.form = newControl;
|
controlDir.form = newControl;
|
||||||
controlDir.ngOnChanges({"form": new SimpleChange(control, newControl)});
|
controlDir.ngOnChanges({'form': new SimpleChange(control, newControl)});
|
||||||
|
|
||||||
checkProperties(newControl);
|
checkProperties(newControl);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validator", () => {
|
it('should set up validator', () => {
|
||||||
expect(control.valid).toBe(true);
|
expect(control.valid).toBe(true);
|
||||||
|
|
||||||
// this will add the required validator and recalculate the validity
|
// this will add the required validator and recalculate the validity
|
||||||
controlDir.ngOnChanges({"form": new SimpleChange(null, control)});
|
controlDir.ngOnChanges({'form': new SimpleChange(null, control)});
|
||||||
|
|
||||||
expect(control.valid).toBe(false);
|
expect(control.valid).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgModel", () => {
|
describe('NgModel', () => {
|
||||||
var ngModel: any /** TODO #9100 */;
|
var ngModel: any /** TODO #9100 */;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ngModel =
|
ngModel =
|
||||||
new NgModel([Validators.required], [asyncValidator("expected")], [defaultAccessor]);
|
new NgModel([Validators.required], [asyncValidator('expected')], [defaultAccessor]);
|
||||||
ngModel.valueAccessor = new DummyControlValueAccessor();
|
ngModel.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
var control = ngModel.control;
|
var control = ngModel.control;
|
||||||
expect(ngModel.control).toBe(control);
|
expect(ngModel.control).toBe(control);
|
||||||
expect(ngModel.value).toBe(control.value);
|
expect(ngModel.value).toBe(control.value);
|
||||||
|
@ -453,34 +426,34 @@ export function main() {
|
||||||
expect(ngModel.untouched).toBe(control.untouched);
|
expect(ngModel.untouched).toBe(control.untouched);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validator", fakeAsync(() => {
|
it('should set up validator', fakeAsync(() => {
|
||||||
// this will add the required validator and recalculate the validity
|
// this will add the required validator and recalculate the validity
|
||||||
ngModel.ngOnChanges({});
|
ngModel.ngOnChanges({});
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(ngModel.control.errors).toEqual({"required": true});
|
expect(ngModel.control.errors).toEqual({'required': true});
|
||||||
|
|
||||||
ngModel.control.updateValue("someValue");
|
ngModel.control.updateValue('someValue');
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(ngModel.control.errors).toEqual({"async": true});
|
expect(ngModel.control.errors).toEqual({'async': true});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgControlName", () => {
|
describe('NgControlName', () => {
|
||||||
var formModel: any /** TODO #9100 */;
|
var formModel: any /** TODO #9100 */;
|
||||||
var controlNameDir: any /** TODO #9100 */;
|
var controlNameDir: any /** TODO #9100 */;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
formModel = new Control("name");
|
formModel = new Control('name');
|
||||||
|
|
||||||
var parent = new NgFormModel([], []);
|
var parent = new NgFormModel([], []);
|
||||||
parent.form = new ControlGroup({"name": formModel});
|
parent.form = new ControlGroup({'name': formModel});
|
||||||
controlNameDir = new NgControlName(parent, [], [], [defaultAccessor]);
|
controlNameDir = new NgControlName(parent, [], [], [defaultAccessor]);
|
||||||
controlNameDir.name = "name";
|
controlNameDir.name = 'name';
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reexport control properties", () => {
|
it('should reexport control properties', () => {
|
||||||
expect(controlNameDir.control).toBe(formModel);
|
expect(controlNameDir.control).toBe(formModel);
|
||||||
expect(controlNameDir.value).toBe(formModel.value);
|
expect(controlNameDir.value).toBe(formModel.value);
|
||||||
expect(controlNameDir.valid).toBe(formModel.valid);
|
expect(controlNameDir.valid).toBe(formModel.valid);
|
||||||
|
|
|
@ -1,67 +1,59 @@
|
||||||
import {
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {Control, FormBuilder} from '@angular/common';
|
import {Control, FormBuilder} from '@angular/common';
|
||||||
|
import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
|
|
||||||
import {PromiseWrapper} from '../../src/facade/promise';
|
import {PromiseWrapper} from '../../src/facade/promise';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
function syncValidator(_: any /** TODO #9100 */): any /** TODO #9100 */ { return null; }
|
function syncValidator(_: any /** TODO #9100 */): any /** TODO #9100 */ { return null; }
|
||||||
function asyncValidator(_: any /** TODO #9100 */) { return PromiseWrapper.resolve(null); }
|
function asyncValidator(_: any /** TODO #9100 */) { return PromiseWrapper.resolve(null); }
|
||||||
|
|
||||||
describe("Form Builder", () => {
|
describe('Form Builder', () => {
|
||||||
var b: any /** TODO #9100 */;
|
var b: any /** TODO #9100 */;
|
||||||
|
|
||||||
beforeEach(() => { b = new FormBuilder(); });
|
beforeEach(() => { b = new FormBuilder(); });
|
||||||
|
|
||||||
it("should create controls from a value", () => {
|
it('should create controls from a value', () => {
|
||||||
var g = b.group({"login": "some value"});
|
var g = b.group({'login': 'some value'});
|
||||||
|
|
||||||
expect(g.controls["login"].value).toEqual("some value");
|
expect(g.controls['login'].value).toEqual('some value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create controls from an array", () => {
|
it('should create controls from an array', () => {
|
||||||
var g = b.group(
|
var g = b.group(
|
||||||
{"login": ["some value"], "password": ["some value", syncValidator, asyncValidator]});
|
{'login': ['some value'], 'password': ['some value', syncValidator, asyncValidator]});
|
||||||
|
|
||||||
expect(g.controls["login"].value).toEqual("some value");
|
expect(g.controls['login'].value).toEqual('some value');
|
||||||
expect(g.controls["password"].value).toEqual("some value");
|
expect(g.controls['password'].value).toEqual('some value');
|
||||||
expect(g.controls["password"].validator).toEqual(syncValidator);
|
expect(g.controls['password'].validator).toEqual(syncValidator);
|
||||||
expect(g.controls["password"].asyncValidator).toEqual(asyncValidator);
|
expect(g.controls['password'].asyncValidator).toEqual(asyncValidator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should use controls", () => {
|
it('should use controls', () => {
|
||||||
var g = b.group({"login": b.control("some value", syncValidator, asyncValidator)});
|
var g = b.group({'login': b.control('some value', syncValidator, asyncValidator)});
|
||||||
|
|
||||||
expect(g.controls["login"].value).toEqual("some value");
|
expect(g.controls['login'].value).toEqual('some value');
|
||||||
expect(g.controls["login"].validator).toBe(syncValidator);
|
expect(g.controls['login'].validator).toBe(syncValidator);
|
||||||
expect(g.controls["login"].asyncValidator).toBe(asyncValidator);
|
expect(g.controls['login'].asyncValidator).toBe(asyncValidator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create groups with optional controls", () => {
|
it('should create groups with optional controls', () => {
|
||||||
var g = b.group({"login": "some value"}, {"optionals": {"login": false}});
|
var g = b.group({'login': 'some value'}, {'optionals': {'login': false}});
|
||||||
|
|
||||||
expect(g.contains("login")).toEqual(false);
|
expect(g.contains('login')).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create groups with a custom validator", () => {
|
it('should create groups with a custom validator', () => {
|
||||||
var g = b.group({"login": "some value"},
|
var g = b.group(
|
||||||
{"validator": syncValidator, "asyncValidator": asyncValidator});
|
{'login': 'some value'}, {'validator': syncValidator, 'asyncValidator': asyncValidator});
|
||||||
|
|
||||||
expect(g.validator).toBe(syncValidator);
|
expect(g.validator).toBe(syncValidator);
|
||||||
expect(g.asyncValidator).toBe(asyncValidator);
|
expect(g.asyncValidator).toBe(asyncValidator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create control arrays", () => {
|
it('should create control arrays', () => {
|
||||||
var c = b.control("three");
|
var c = b.control('three');
|
||||||
var a = b.array(["one", ["two", syncValidator], c, b.array(['four'])], syncValidator,
|
var a = b.array(
|
||||||
asyncValidator);
|
['one', ['two', syncValidator], c, b.array(['four'])], syncValidator, asyncValidator);
|
||||||
|
|
||||||
expect(a.value).toEqual(['one', 'two', 'three', ['four']]);
|
expect(a.value).toEqual(['one', 'two', 'three', ['four']]);
|
||||||
expect(a.validator).toBe(syncValidator);
|
expect(a.validator).toBe(syncValidator);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,9 @@
|
||||||
import {
|
import {AbstractControl, Control, ControlArray, ControlGroup, Validators} from '@angular/common';
|
||||||
ddescribe,
|
import {Log, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
|
||||||
describe,
|
import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {fakeAsync, flushMicrotasks, Log, tick} from '@angular/core/testing';
|
|
||||||
import {ControlGroup, Control, Validators, AbstractControl, ControlArray} from '@angular/common';
|
|
||||||
import {PromiseWrapper} from '../../src/facade/promise';
|
|
||||||
import {EventEmitter, ObservableWrapper, TimerWrapper} from '../../src/facade/async';
|
import {EventEmitter, ObservableWrapper, TimerWrapper} from '../../src/facade/async';
|
||||||
|
import {PromiseWrapper} from '../../src/facade/promise';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
function validator(key: string, error: any) {
|
function validator(key: string, error: any) {
|
||||||
|
@ -22,95 +14,98 @@ export function main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("Validators", () => {
|
describe('Validators', () => {
|
||||||
describe("required", () => {
|
describe('required', () => {
|
||||||
it("should error on an empty string",
|
it('should error on an empty string',
|
||||||
() => { expect(Validators.required(new Control(""))).toEqual({"required": true}); });
|
() => { expect(Validators.required(new Control(''))).toEqual({'required': true}); });
|
||||||
|
|
||||||
it("should error on null",
|
it('should error on null',
|
||||||
() => { expect(Validators.required(new Control(null))).toEqual({"required": true}); });
|
() => { expect(Validators.required(new Control(null))).toEqual({'required': true}); });
|
||||||
|
|
||||||
it("should not error on a non-empty string",
|
it('should not error on a non-empty string',
|
||||||
() => { expect(Validators.required(new Control("not empty"))).toEqual(null); });
|
() => { expect(Validators.required(new Control('not empty'))).toEqual(null); });
|
||||||
|
|
||||||
it("should accept zero as valid",
|
it('should accept zero as valid',
|
||||||
() => { expect(Validators.required(new Control(0))).toEqual(null); });
|
() => { expect(Validators.required(new Control(0))).toEqual(null); });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("minLength", () => {
|
describe('minLength', () => {
|
||||||
it("should not error on an empty string",
|
it('should not error on an empty string',
|
||||||
() => { expect(Validators.minLength(2)(new Control(""))).toEqual(null); });
|
() => { expect(Validators.minLength(2)(new Control(''))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on null",
|
it('should not error on null',
|
||||||
() => { expect(Validators.minLength(2)(new Control(null))).toEqual(null); });
|
() => { expect(Validators.minLength(2)(new Control(null))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on valid strings",
|
it('should not error on valid strings',
|
||||||
() => { expect(Validators.minLength(2)(new Control("aa"))).toEqual(null); });
|
() => { expect(Validators.minLength(2)(new Control('aa'))).toEqual(null); });
|
||||||
|
|
||||||
it("should error on short strings", () => {
|
it('should error on short strings', () => {
|
||||||
expect(Validators.minLength(2)(new Control("a")))
|
expect(Validators.minLength(2)(new Control('a'))).toEqual({
|
||||||
.toEqual({"minlength": {"requiredLength": 2, "actualLength": 1}});
|
'minlength': {'requiredLength': 2, 'actualLength': 1}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("maxLength", () => {
|
describe('maxLength', () => {
|
||||||
it("should not error on an empty string",
|
it('should not error on an empty string',
|
||||||
() => { expect(Validators.maxLength(2)(new Control(""))).toEqual(null); });
|
() => { expect(Validators.maxLength(2)(new Control(''))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on null",
|
it('should not error on null',
|
||||||
() => { expect(Validators.maxLength(2)(new Control(null))).toEqual(null); });
|
() => { expect(Validators.maxLength(2)(new Control(null))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on valid strings",
|
it('should not error on valid strings',
|
||||||
() => { expect(Validators.maxLength(2)(new Control("aa"))).toEqual(null); });
|
() => { expect(Validators.maxLength(2)(new Control('aa'))).toEqual(null); });
|
||||||
|
|
||||||
it("should error on long strings", () => {
|
it('should error on long strings', () => {
|
||||||
expect(Validators.maxLength(2)(new Control("aaa")))
|
expect(Validators.maxLength(2)(new Control('aaa'))).toEqual({
|
||||||
.toEqual({"maxlength": {"requiredLength": 2, "actualLength": 3}});
|
'maxlength': {'requiredLength': 2, 'actualLength': 3}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("pattern", () => {
|
describe('pattern', () => {
|
||||||
it("should not error on an empty string",
|
it('should not error on an empty string',
|
||||||
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control(""))).toEqual(null); });
|
() => { expect(Validators.pattern('[a-zA-Z ]*')(new Control(''))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on null",
|
it('should not error on null',
|
||||||
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control(null))).toEqual(null); });
|
() => { expect(Validators.pattern('[a-zA-Z ]*')(new Control(null))).toEqual(null); });
|
||||||
|
|
||||||
it("should not error on valid strings",
|
it('should not error on valid strings',
|
||||||
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control("aaAA"))).toEqual(null); });
|
() => { expect(Validators.pattern('[a-zA-Z ]*')(new Control('aaAA'))).toEqual(null); });
|
||||||
|
|
||||||
it("should error on failure to match string", () => {
|
it('should error on failure to match string', () => {
|
||||||
expect(Validators.pattern("[a-zA-Z ]*")(new Control("aaa0")))
|
expect(Validators.pattern('[a-zA-Z ]*')(new Control('aaa0'))).toEqual({
|
||||||
.toEqual({"pattern": {"requiredPattern": "^[a-zA-Z ]*$", "actualValue": "aaa0"}});
|
'pattern': {'requiredPattern': '^[a-zA-Z ]*$', 'actualValue': 'aaa0'}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("compose", () => {
|
describe('compose', () => {
|
||||||
it("should return null when given null",
|
it('should return null when given null',
|
||||||
() => { expect(Validators.compose(null)).toBe(null); });
|
() => { expect(Validators.compose(null)).toBe(null); });
|
||||||
|
|
||||||
it("should collect errors from all the validators", () => {
|
it('should collect errors from all the validators', () => {
|
||||||
var c = Validators.compose([validator("a", true), validator("b", true)]);
|
var c = Validators.compose([validator('a', true), validator('b', true)]);
|
||||||
expect(c(new Control(""))).toEqual({"a": true, "b": true});
|
expect(c(new Control(''))).toEqual({'a': true, 'b': true});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should run validators left to right", () => {
|
it('should run validators left to right', () => {
|
||||||
var c = Validators.compose([validator("a", 1), validator("a", 2)]);
|
var c = Validators.compose([validator('a', 1), validator('a', 2)]);
|
||||||
expect(c(new Control(""))).toEqual({"a": 2});
|
expect(c(new Control(''))).toEqual({'a': 2});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return null when no errors", () => {
|
it('should return null when no errors', () => {
|
||||||
var c = Validators.compose([Validators.nullValidator, Validators.nullValidator]);
|
var c = Validators.compose([Validators.nullValidator, Validators.nullValidator]);
|
||||||
expect(c(new Control(""))).toEqual(null);
|
expect(c(new Control(''))).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should ignore nulls", () => {
|
it('should ignore nulls', () => {
|
||||||
var c = Validators.compose([null, Validators.required]);
|
var c = Validators.compose([null, Validators.required]);
|
||||||
expect(c(new Control(""))).toEqual({"required": true});
|
expect(c(new Control(''))).toEqual({'required': true});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("composeAsync", () => {
|
describe('composeAsync', () => {
|
||||||
function asyncValidator(expected: any /** TODO #9100 */, response: any /** TODO #9100 */) {
|
function asyncValidator(expected: any /** TODO #9100 */, response: any /** TODO #9100 */) {
|
||||||
return (c: any /** TODO #9100 */) => {
|
return (c: any /** TODO #9100 */) => {
|
||||||
var emitter = new EventEmitter();
|
var emitter = new EventEmitter();
|
||||||
|
@ -127,43 +122,42 @@ export function main() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should return null when given null",
|
it('should return null when given null',
|
||||||
() => { expect(Validators.composeAsync(null)).toEqual(null); });
|
() => { expect(Validators.composeAsync(null)).toEqual(null); });
|
||||||
|
|
||||||
it("should collect errors from all the validators", fakeAsync(() => {
|
it('should collect errors from all the validators', fakeAsync(() => {
|
||||||
var c = Validators.composeAsync([
|
var c = Validators.composeAsync([
|
||||||
asyncValidator("expected", {"one": true}),
|
asyncValidator('expected', {'one': true}), asyncValidator('expected', {'two': true})
|
||||||
asyncValidator("expected", {"two": true})
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var value: any /** TODO #9100 */ = null;
|
var value: any /** TODO #9100 */ = null;
|
||||||
(<Promise<any>>c(new Control("invalid"))).then(v => value = v);
|
(<Promise<any>>c(new Control('invalid'))).then(v => value = v);
|
||||||
|
|
||||||
tick(1);
|
tick(1);
|
||||||
|
|
||||||
expect(value).toEqual({"one": true, "two": true});
|
expect(value).toEqual({'one': true, 'two': true});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should return null when no errors", fakeAsync(() => {
|
it('should return null when no errors', fakeAsync(() => {
|
||||||
var c = Validators.composeAsync([asyncValidator("expected", {"one": true})]);
|
var c = Validators.composeAsync([asyncValidator('expected', {'one': true})]);
|
||||||
|
|
||||||
var value: any /** TODO #9100 */ = null;
|
var value: any /** TODO #9100 */ = null;
|
||||||
(<Promise<any>>c(new Control("expected"))).then(v => value = v);
|
(<Promise<any>>c(new Control('expected'))).then(v => value = v);
|
||||||
|
|
||||||
tick(1);
|
tick(1);
|
||||||
|
|
||||||
expect(value).toEqual(null);
|
expect(value).toEqual(null);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should ignore nulls", fakeAsync(() => {
|
it('should ignore nulls', fakeAsync(() => {
|
||||||
var c = Validators.composeAsync([asyncValidator("expected", {"one": true}), null]);
|
var c = Validators.composeAsync([asyncValidator('expected', {'one': true}), null]);
|
||||||
|
|
||||||
var value: any /** TODO #9100 */ = null;
|
var value: any /** TODO #9100 */ = null;
|
||||||
(<Promise<any>>c(new Control("invalid"))).then(v => value = v);
|
(<Promise<any>>c(new Control('invalid'))).then(v => value = v);
|
||||||
|
|
||||||
tick(1);
|
tick(1);
|
||||||
|
|
||||||
expect(value).toEqual({"one": true});
|
expect(value).toEqual({'one': true});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,31 +1,16 @@
|
||||||
import {
|
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, inject,} from '@angular/core/testing/testing_internal';
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach,
|
|
||||||
inject,
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||||
import {SpyChangeDetectorRef} from '../spies';
|
import {SpyChangeDetectorRef} from '../spies';
|
||||||
import {isBlank} from '../../src/facade/lang';
|
import {isBlank} from '../../src/facade/lang';
|
||||||
import {AsyncPipe} from '@angular/common';
|
import {AsyncPipe} from '@angular/common';
|
||||||
import {WrappedValue} from '@angular/core';
|
import {WrappedValue} from '@angular/core';
|
||||||
import {
|
import {EventEmitter, ObservableWrapper, PromiseWrapper, TimerWrapper} from '../../src/facade/async';
|
||||||
EventEmitter,
|
|
||||||
ObservableWrapper,
|
|
||||||
PromiseWrapper,
|
|
||||||
TimerWrapper
|
|
||||||
} from '../../src/facade/async';
|
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
import {PromiseCompleter} from '../../src/facade/promise';
|
import {PromiseCompleter} from '../../src/facade/promise';
|
||||||
import {browserDetection} from '@angular/platform-browser/testing';
|
import {browserDetection} from '@angular/platform-browser/testing';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe("AsyncPipe", () => {
|
describe('AsyncPipe', () => {
|
||||||
|
|
||||||
describe('Observable', () => {
|
describe('Observable', () => {
|
||||||
var emitter: any /** TODO #9100 */;
|
var emitter: any /** TODO #9100 */;
|
||||||
|
@ -39,11 +24,11 @@ export function main() {
|
||||||
pipe = new AsyncPipe(ref);
|
pipe = new AsyncPipe(ref);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("transform", () => {
|
describe('transform', () => {
|
||||||
it("should return null when subscribing to an observable",
|
it('should return null when subscribing to an observable',
|
||||||
() => { expect(pipe.transform(emitter)).toBe(null); });
|
() => { expect(pipe.transform(emitter)).toBe(null); });
|
||||||
|
|
||||||
it("should return the latest available value wrapped",
|
it('should return the latest available value wrapped',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(emitter);
|
pipe.transform(emitter);
|
||||||
|
|
||||||
|
@ -56,7 +41,7 @@ export function main() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it("should return same value when nothing has changed since the last call",
|
it('should return same value when nothing has changed since the last call',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(emitter);
|
pipe.transform(emitter);
|
||||||
ObservableWrapper.callEmit(emitter, message);
|
ObservableWrapper.callEmit(emitter, message);
|
||||||
|
@ -68,7 +53,7 @@ export function main() {
|
||||||
}, 0)
|
}, 0)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should dispose of the existing subscription when subscribing to a new observable",
|
it('should dispose of the existing subscription when subscribing to a new observable',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(emitter);
|
pipe.transform(emitter);
|
||||||
|
|
||||||
|
@ -84,7 +69,7 @@ export function main() {
|
||||||
}, 0)
|
}, 0)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should request a change detection check upon receiving a new value",
|
it('should request a change detection check upon receiving a new value',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(emitter);
|
pipe.transform(emitter);
|
||||||
ObservableWrapper.callEmit(emitter, message);
|
ObservableWrapper.callEmit(emitter, message);
|
||||||
|
@ -96,11 +81,12 @@ export function main() {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("ngOnDestroy", () => {
|
describe('ngOnDestroy', () => {
|
||||||
it("should do nothing when no subscription",
|
it('should do nothing when no subscription',
|
||||||
() => { expect(() => pipe.ngOnDestroy()).not.toThrow(); });
|
() => { expect(() => pipe.ngOnDestroy()).not.toThrow(); });
|
||||||
|
|
||||||
it("should dispose of the existing subscription", inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
it('should dispose of the existing subscription',
|
||||||
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(emitter);
|
pipe.transform(emitter);
|
||||||
pipe.ngOnDestroy();
|
pipe.ngOnDestroy();
|
||||||
|
|
||||||
|
@ -114,7 +100,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Promise", () => {
|
describe('Promise', () => {
|
||||||
var message = new Object();
|
var message = new Object();
|
||||||
var pipe: AsyncPipe;
|
var pipe: AsyncPipe;
|
||||||
var completer: PromiseCompleter<any>;
|
var completer: PromiseCompleter<any>;
|
||||||
|
@ -128,11 +114,12 @@ export function main() {
|
||||||
pipe = new AsyncPipe(<any>ref);
|
pipe = new AsyncPipe(<any>ref);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("transform", () => {
|
describe('transform', () => {
|
||||||
it("should return null when subscribing to a promise",
|
it('should return null when subscribing to a promise',
|
||||||
() => { expect(pipe.transform(completer.promise)).toBe(null); });
|
() => { expect(pipe.transform(completer.promise)).toBe(null); });
|
||||||
|
|
||||||
it("should return the latest available value", inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
it('should return the latest available value',
|
||||||
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(completer.promise);
|
pipe.transform(completer.promise);
|
||||||
|
|
||||||
completer.resolve(message);
|
completer.resolve(message);
|
||||||
|
@ -143,7 +130,7 @@ export function main() {
|
||||||
}, timer)
|
}, timer)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should return unwrapped value when nothing has changed since the last call",
|
it('should return unwrapped value when nothing has changed since the last call',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(completer.promise);
|
pipe.transform(completer.promise);
|
||||||
completer.resolve(message);
|
completer.resolve(message);
|
||||||
|
@ -155,7 +142,7 @@ export function main() {
|
||||||
}, timer)
|
}, timer)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should dispose of the existing subscription when subscribing to a new promise",
|
it('should dispose of the existing subscription when subscribing to a new promise',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(completer.promise);
|
pipe.transform(completer.promise);
|
||||||
|
|
||||||
|
@ -171,7 +158,7 @@ export function main() {
|
||||||
}, timer)
|
}, timer)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should request a change detection check upon receiving a new value",
|
it('should request a change detection check upon receiving a new value',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
var markForCheck = ref.spy('markForCheck');
|
var markForCheck = ref.spy('markForCheck');
|
||||||
pipe.transform(completer.promise);
|
pipe.transform(completer.promise);
|
||||||
|
@ -183,22 +170,23 @@ export function main() {
|
||||||
}, timer)
|
}, timer)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe("ngOnDestroy", () => {
|
describe('ngOnDestroy', () => {
|
||||||
it("should do nothing when no source",
|
it('should do nothing when no source',
|
||||||
() => { expect(() => pipe.ngOnDestroy()).not.toThrow(); });
|
() => { expect(() => pipe.ngOnDestroy()).not.toThrow(); });
|
||||||
|
|
||||||
it("should dispose of the existing source", inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
it('should dispose of the existing source',
|
||||||
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
pipe.transform(completer.promise);
|
pipe.transform(completer.promise);
|
||||||
expect(pipe.transform(completer.promise)).toBe(null);
|
expect(pipe.transform(completer.promise)).toBe(null);
|
||||||
completer.resolve(message)
|
completer.resolve(message)
|
||||||
|
|
||||||
|
|
||||||
TimerWrapper.setTimeout(() => {
|
TimerWrapper.setTimeout(() => {
|
||||||
expect(pipe.transform(completer.promise)).toEqual(new WrappedValue(message));
|
expect(pipe.transform(completer.promise)).toEqual(new WrappedValue(message));
|
||||||
pipe.ngOnDestroy();
|
pipe.ngOnDestroy();
|
||||||
expect(pipe.transform(completer.promise)).toBe(null);
|
expect(pipe.transform(completer.promise)).toBe(null);
|
||||||
async.done();
|
async.done();
|
||||||
}, timer);
|
}, timer);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -214,7 +202,7 @@ export function main() {
|
||||||
describe('other types', () => {
|
describe('other types', () => {
|
||||||
it('should throw when given an invalid object', () => {
|
it('should throw when given an invalid object', () => {
|
||||||
var pipe = new AsyncPipe(null);
|
var pipe = new AsyncPipe(null);
|
||||||
expect(() => pipe.transform(<any>"some bogus object")).toThrowError();
|
expect(() => pipe.transform(<any>'some bogus object')).toThrowError();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,21 +1,12 @@
|
||||||
import {
|
import {DatePipe} from '@angular/common';
|
||||||
ddescribe,
|
import {PipeResolver} from '@angular/compiler/src/pipe_resolver';
|
||||||
describe,
|
import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
import {browserDetection} from '@angular/platform-browser/testing';
|
import {browserDetection} from '@angular/platform-browser/testing';
|
||||||
|
|
||||||
import {DatePipe} from '@angular/common';
|
|
||||||
import {DateWrapper} from '../../src/facade/lang';
|
import {DateWrapper} from '../../src/facade/lang';
|
||||||
import {PipeResolver} from '@angular/compiler/src/pipe_resolver';
|
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe("DatePipe", () => {
|
describe('DatePipe', () => {
|
||||||
var date: any /** TODO #9100 */;
|
var date: any /** TODO #9100 */;
|
||||||
var pipe: any /** TODO #9100 */;
|
var pipe: any /** TODO #9100 */;
|
||||||
|
|
||||||
|
@ -27,23 +18,23 @@ export function main() {
|
||||||
it('should be marked as pure',
|
it('should be marked as pure',
|
||||||
() => { expect(new PipeResolver().resolve(DatePipe).pure).toEqual(true); });
|
() => { expect(new PipeResolver().resolve(DatePipe).pure).toEqual(true); });
|
||||||
|
|
||||||
describe("supports", () => {
|
describe('supports', () => {
|
||||||
it("should support date", () => { expect(pipe.supports(date)).toBe(true); });
|
it('should support date', () => { expect(pipe.supports(date)).toBe(true); });
|
||||||
it("should support int", () => { expect(pipe.supports(123456789)).toBe(true); });
|
it('should support int', () => { expect(pipe.supports(123456789)).toBe(true); });
|
||||||
it("should support ISO string",
|
it('should support ISO string',
|
||||||
() => { expect(pipe.supports("2015-06-15T21:43:11Z")).toBe(true); });
|
() => { expect(pipe.supports('2015-06-15T21:43:11Z')).toBe(true); });
|
||||||
|
|
||||||
it("should not support other objects", () => {
|
it('should not support other objects', () => {
|
||||||
expect(pipe.supports(new Object())).toBe(false);
|
expect(pipe.supports(new Object())).toBe(false);
|
||||||
expect(pipe.supports(null)).toBe(false);
|
expect(pipe.supports(null)).toBe(false);
|
||||||
expect(pipe.supports("")).toBe(false);
|
expect(pipe.supports('')).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO(mlaval): enable tests when Intl API is no longer used, see
|
// TODO(mlaval): enable tests when Intl API is no longer used, see
|
||||||
// https://github.com/angular/angular/issues/3333
|
// https://github.com/angular/angular/issues/3333
|
||||||
if (browserDetection.supportsIntlApi) {
|
if (browserDetection.supportsIntlApi) {
|
||||||
describe("transform", () => {
|
describe('transform', () => {
|
||||||
it('should format each component correctly', () => {
|
it('should format each component correctly', () => {
|
||||||
expect(pipe.transform(date, 'y')).toEqual('2015');
|
expect(pipe.transform(date, 'y')).toEqual('2015');
|
||||||
expect(pipe.transform(date, 'yy')).toEqual('15');
|
expect(pipe.transform(date, 'yy')).toEqual('15');
|
||||||
|
|
|
@ -1,57 +1,50 @@
|
||||||
import {
|
|
||||||
ddescribe,
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
xit,
|
|
||||||
expect,
|
|
||||||
beforeEach,
|
|
||||||
afterEach
|
|
||||||
} from '@angular/core/testing/testing_internal';
|
|
||||||
|
|
||||||
import {I18nPluralPipe} from '@angular/common';
|
import {I18nPluralPipe} from '@angular/common';
|
||||||
import {PipeResolver} from '@angular/compiler/src/pipe_resolver';
|
import {PipeResolver} from '@angular/compiler/src/pipe_resolver';
|
||||||
|
import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe("I18nPluralPipe", () => {
|
describe('I18nPluralPipe', () => {
|
||||||
var pipe: any /** TODO #9100 */;
|
var pipe: any /** TODO #9100 */;
|
||||||
var mapping = {'=0': 'No messages.', '=1': 'One message.', 'other': 'There are some messages.'};
|
var mapping = {'=0': 'No messages.', '=1': 'One message.', 'other': 'There are some messages.'};
|
||||||
var interpolatedMapping =
|
var interpolatedMapping = {
|
||||||
{'=0': 'No messages.', '=1': 'One message.', 'other': 'There are # messages, that is #.'};
|
'=0': 'No messages.',
|
||||||
|
'=1': 'One message.',
|
||||||
|
'other': 'There are # messages, that is #.'
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => { pipe = new I18nPluralPipe(); });
|
beforeEach(() => { pipe = new I18nPluralPipe(); });
|
||||||
|
|
||||||
it('should be marked as pure',
|
it('should be marked as pure',
|
||||||
() => { expect(new PipeResolver().resolve(I18nPluralPipe).pure).toEqual(true); });
|
() => { expect(new PipeResolver().resolve(I18nPluralPipe).pure).toEqual(true); });
|
||||||
|
|
||||||
describe("transform", () => {
|
describe('transform', () => {
|
||||||
it("should return 0 text if value is 0", () => {
|
it('should return 0 text if value is 0', () => {
|
||||||
var val = pipe.transform(0, mapping);
|
var val = pipe.transform(0, mapping);
|
||||||
expect(val).toEqual('No messages.');
|
expect(val).toEqual('No messages.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return 1 text if value is 1", () => {
|
it('should return 1 text if value is 1', () => {
|
||||||
var val = pipe.transform(1, mapping);
|
var val = pipe.transform(1, mapping);
|
||||||
expect(val).toEqual('One message.');
|
expect(val).toEqual('One message.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return other text if value is anything other than 0 or 1", () => {
|
it('should return other text if value is anything other than 0 or 1', () => {
|
||||||
var val = pipe.transform(6, mapping);
|
var val = pipe.transform(6, mapping);
|
||||||
expect(val).toEqual('There are some messages.');
|
expect(val).toEqual('There are some messages.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should interpolate the value into the text where indicated", () => {
|
it('should interpolate the value into the text where indicated', () => {
|
||||||
var val = pipe.transform(6, interpolatedMapping);
|
var val = pipe.transform(6, interpolatedMapping);
|
||||||
expect(val).toEqual('There are 6 messages, that is 6.');
|
expect(val).toEqual('There are 6 messages, that is 6.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should use 'other' if value is undefined", () => {
|
it('should use \'other\' if value is undefined', () => {
|
||||||
var messageLength: any /** TODO #9100 */;
|
var messageLength: any /** TODO #9100 */;
|
||||||
var val = pipe.transform(messageLength, interpolatedMapping);
|
var val = pipe.transform(messageLength, interpolatedMapping);
|
||||||
expect(val).toEqual('There are messages, that is .');
|
expect(val).toEqual('There are messages, that is .');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not support bad arguments",
|
it('should not support bad arguments',
|
||||||
() => { expect(() => pipe.transform(0, 'hey')).toThrowError(); });
|
() => { expect(() => pipe.transform(0, 'hey')).toThrowError(); });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue