From 9d265b6f6187bcd2c4342ba1431895029e19a0d4 Mon Sep 17 00:00:00 2001 From: Kara Date: Thu, 7 Jul 2016 11:32:51 -0700 Subject: [PATCH] feat(forms): add modules for forms and deprecatedForms (#9859) Closes #9732 BREAKING CHANGE: We have removed the deprecated form directives from the built-in platform directive list, so apps are not required to package forms with their app. This also makes forms friendly to offline compilation. Instead, we have exposed three modules: OLD API: - `DeprecatedFormsModule` NEW API: - `FormsModule` - `ReactiveFormsModule` If you provide one of these modules, the default forms directives and providers from that module will be available to you app-wide. Note: You can provide both the `FormsModule` and the `ReactiveFormsModule` together if you like, but they are fully-functional separately. **Before:** ```ts import {disableDeprecatedForms, provideForms} from @angular/forms; bootstrap(App, [ disableDeprecatedForms(), provideForms() ]); ``` **After:** ```ts import {DeprecatedFormsModule} from @angular/common; bootstrap(App, {modules: [DeprecatedFormsModule] }); ``` -OR- ```ts import {FormsModule} from @angular/forms; bootstrap(App, {modules: [FormsModule] }); ``` -OR- ```ts import {ReactiveFormsModule} from @angular/forms; bootstrap(App, {modules: [ReactiveFormsModule] }); ``` You can also choose not to provide any forms module and run your app without forms. Or you can choose not to provide any forms module *and* provide form directives at will. This will allow you to use the deprecatedForms API for some components and not others. ``` import {FORM_DIRECTIVES, FORM_PROVIDERS} from @angular/forms; @Component({ selector: some-comp, directives: [FORM_DIRECTIVES], providers: [FORM_PROVIDERS] }) class SomeComp ``` --- .../@angular/common/src/common_directives.ts | 4 +- .../@angular/common/src/forms-deprecated.ts | 18 +- .../test/forms-deprecated/integration_spec.ts | 11 +- modules/@angular/forms/src/directives.ts | 29 +- modules/@angular/forms/src/form_providers.ts | 65 +- .../@angular/forms/test/integration_spec.ts | 1209 ++++++++--------- .../@angular/platform-browser/src/browser.ts | 4 +- tools/public_api_guard/common/index.d.ts | 4 + tools/public_api_guard/forms/index.d.ts | 17 +- 9 files changed, 606 insertions(+), 755 deletions(-) diff --git a/modules/@angular/common/src/common_directives.ts b/modules/@angular/common/src/common_directives.ts index f1ad4cb1df..dc54725474 100644 --- a/modules/@angular/common/src/common_directives.ts +++ b/modules/@angular/common/src/common_directives.ts @@ -9,8 +9,6 @@ import {Type} from '@angular/core'; 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 @@ -57,4 +55,4 @@ import {FORM_DIRECTIVES} from './forms-deprecated'; * * @experimental Contains forms which are experimental. */ -export const COMMON_DIRECTIVES: Type[][] = /*@ts2dart_const*/[CORE_DIRECTIVES, FORM_DIRECTIVES]; +export const COMMON_DIRECTIVES: Type[][] = /*@ts2dart_const*/[CORE_DIRECTIVES]; diff --git a/modules/@angular/common/src/forms-deprecated.ts b/modules/@angular/common/src/forms-deprecated.ts index ef8c18e804..d6484feaa9 100644 --- a/modules/@angular/common/src/forms-deprecated.ts +++ b/modules/@angular/common/src/forms-deprecated.ts @@ -18,8 +18,9 @@ * Forms providers are not included in default providers; you must import these providers * explicitly. */ -import {Type} from '@angular/core'; +import {AppModule, Type} from '@angular/core'; +import {FORM_DIRECTIVES} from './forms-deprecated/directives'; import {RadioControlRegistry} from './forms-deprecated/directives/radio_control_value_accessor'; import {FormBuilder} from './forms-deprecated/form_builder'; @@ -57,3 +58,18 @@ export {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from './forms-deprecated * @experimental */ export const FORM_PROVIDERS: Type[] = /*@ts2dart_const*/[FormBuilder, RadioControlRegistry]; + + +/** + * The app module for the deprecated forms API. + * @deprecated + */ +@AppModule({ + providers: [ + FORM_PROVIDERS, + ], + directives: FORM_DIRECTIVES, + pipes: [] +}) +export class DeprecatedFormsModule { +} diff --git a/modules/@angular/common/test/forms-deprecated/integration_spec.ts b/modules/@angular/common/test/forms-deprecated/integration_spec.ts index 090932d2c1..1e33f2a445 100644 --- a/modules/@angular/common/test/forms-deprecated/integration_spec.ts +++ b/modules/@angular/common/test/forms-deprecated/integration_spec.ts @@ -7,11 +7,11 @@ */ import {NgFor, NgIf} from '@angular/common'; -import {Control, ControlGroup, ControlValueAccessor, FORM_DIRECTIVES, FORM_PROVIDERS, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, NgForm, RadioButtonState, Validator, Validators} from '@angular/common/src/forms-deprecated'; +import {Control, ControlGroup, ControlValueAccessor, DeprecatedFormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, NgForm, RadioButtonState, Validator, Validators} from '@angular/common/src/forms-deprecated'; import {TestComponentBuilder} from '@angular/compiler/testing'; import {Component, Directive, EventEmitter, Output} from '@angular/core'; import {Input, Provider, forwardRef} from '@angular/core'; -import {ComponentFixture, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; +import {ComponentFixture, configureModule, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; import {By} from '@angular/platform-browser/src/dom/debug/by'; @@ -25,6 +25,8 @@ import {PromiseWrapper} from '../../src/facade/promise'; export function main() { describe('integration tests', () => { + beforeEach(() => {configureModule({modules: [DeprecatedFormsModule]})}); + it('should initialize DOM elements with the given form object', inject( [TestComponentBuilder, AsyncTestCompleter], @@ -1548,10 +1550,7 @@ class UniqLoginValidator implements Validator { @Component({ selector: 'my-comp', template: '', - directives: [ - FORM_DIRECTIVES, WrappedValue, MyInput, NgIf, NgFor, LoginIsEmptyValidator, UniqLoginValidator - ], - providers: [FORM_PROVIDERS] + directives: [WrappedValue, MyInput, NgIf, NgFor, LoginIsEmptyValidator, UniqLoginValidator] }) class MyComp8 { form: any; diff --git a/modules/@angular/forms/src/directives.ts b/modules/@angular/forms/src/directives.ts index 3528f71c0f..ed57d9f026 100644 --- a/modules/@angular/forms/src/directives.ts +++ b/modules/@angular/forms/src/directives.ts @@ -44,7 +44,18 @@ export {NgSelectOption, SelectControlValueAccessor} from './directives/select_co export {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor'; export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators'; +const SHARED_FORM_DIRECTIVES: Type[] = /*@ts2dart_const*/[ + NgSelectOption, NgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, + CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, + RadioControlValueAccessor, NgControlStatus, RequiredValidator, MinLengthValidator, + MaxLengthValidator, PatternValidator +]; +const TEMPLATE_DRIVEN_DIRECTIVES: Type[] = /*@ts2dart_const*/[NgModel, NgModelGroup, NgForm]; + +const REACTIVE_DRIVEN_DIRECTIVES: Type[] = /*@ts2dart_const*/[ + FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName +]; /** * @@ -63,20 +74,12 @@ export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValida * ``` * @experimental */ -export const FORM_DIRECTIVES: Type[] = /*@ts2dart_const*/[ - NgModel, NgModelGroup, NgForm, - - NgSelectOption, NgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, - CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, - RadioControlValueAccessor, NgControlStatus, - - RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator -]; +export const FORM_DIRECTIVES: Type[][] = + /*@ts2dart_const*/[TEMPLATE_DRIVEN_DIRECTIVES, SHARED_FORM_DIRECTIVES]; /** * @experimental */ -export const REACTIVE_FORM_DIRECTIVES: Type[] = - /*@ts2dart_const*/[ - FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName - ]; + +export const REACTIVE_FORM_DIRECTIVES: Type[][] = + /*@ts2dart_const*/[REACTIVE_DRIVEN_DIRECTIVES, SHARED_FORM_DIRECTIVES]; diff --git a/modules/@angular/forms/src/form_providers.ts b/modules/@angular/forms/src/form_providers.ts index c673c7c8ac..82aed7e0aa 100644 --- a/modules/@angular/forms/src/form_providers.ts +++ b/modules/@angular/forms/src/form_providers.ts @@ -6,64 +6,37 @@ * found in the LICENSE file at https://angular.io/license */ - -import {COMMON_DIRECTIVES, FORM_DIRECTIVES as OLD_FORM_DIRECTIVES, FORM_PROVIDERS as OLD_FORM_PROVIDERS} from '@angular/common'; -import {CompilerConfig} from '@angular/compiler'; -import {PLATFORM_DIRECTIVES, PLATFORM_PIPES, Type} from '@angular/core'; - -import {FORM_DIRECTIVES as NEW_FORM_DIRECTIVES} from './directives'; -import {RadioControlRegistry as NewRadioControlRegistry} from './directives/radio_control_value_accessor'; -import {ListWrapper} from './facade/collection'; -import {FormBuilder as NewFormBuilder} from './form_builder'; - +import {AppModule, Type} from '@angular/core'; +import {FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES} from './directives'; +import {RadioControlRegistry} from './directives/radio_control_value_accessor'; +import {FormBuilder} from './form_builder'; /** * Shorthand set of providers used for building Angular forms. - * - * ### Example - * - * ```typescript - * bootstrap(MyApp, [FORM_PROVIDERS]); - * ``` - * * @experimental */ -export const FORM_PROVIDERS: Type[] = /*@ts2dart_const*/[NewFormBuilder, NewRadioControlRegistry]; - -function flatten(platformDirectives: any[]): any[] { - let flattenedDirectives: any[] = []; - platformDirectives.forEach((directives) => { - if (Array.isArray(directives)) { - flattenedDirectives = flattenedDirectives.concat(directives); - } else { - flattenedDirectives.push(directives); - } - }); - return flattenedDirectives; -} - +export const FORM_PROVIDERS: Type[] = /*@ts2dart_const*/[RadioControlRegistry]; /** + * Shorthand set of providers used for building reactive Angular forms. * @experimental */ -export function disableDeprecatedForms(): any[] { - return [{ - provide: CompilerConfig, - useFactory: (platformDirectives: any[], platformPipes: any[]) => { - const flattenedDirectives = flatten(platformDirectives); - ListWrapper.remove(flattenedDirectives, OLD_FORM_DIRECTIVES); - return new CompilerConfig({platformDirectives: flattenedDirectives, platformPipes}); - }, - deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES] - }]; +export const REACTIVE_FORM_PROVIDERS: Type[] = + /*@ts2dart_const*/[FormBuilder, RadioControlRegistry]; + +/** + * The app module for forms. + * @experimental + */ +@AppModule({providers: [FORM_PROVIDERS], directives: FORM_DIRECTIVES, pipes: []}) +export class FormsModule { } /** + * The app module for reactive forms. * @experimental */ -export function provideForms(): any[] { - return [ - {provide: PLATFORM_DIRECTIVES, useValue: NEW_FORM_DIRECTIVES, multi: true}, FORM_PROVIDERS - ]; -} +@AppModule({providers: [REACTIVE_FORM_PROVIDERS], directives: REACTIVE_FORM_DIRECTIVES, pipes: []}) +export class ReactiveFormsModule { +} \ No newline at end of file diff --git a/modules/@angular/forms/test/integration_spec.ts b/modules/@angular/forms/test/integration_spec.ts index bf7bb88ee7..848c67e344 100644 --- a/modules/@angular/forms/test/integration_spec.ts +++ b/modules/@angular/forms/test/integration_spec.ts @@ -10,11 +10,10 @@ import {NgFor, NgIf} from '@angular/common'; import {TestComponentBuilder} from '@angular/compiler/testing'; import {Component, Directive, EventEmitter, Output} from '@angular/core'; import {Input, Provider, forwardRef} from '@angular/core'; -import {ComponentFixture} from '@angular/core/testing'; -import {fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; +import {ComponentFixture, configureModule, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; -import {ControlValueAccessor, FORM_DIRECTIVES, FORM_PROVIDERS, FormArray, FormControl, FormGroup, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, NgForm, NgModel, REACTIVE_FORM_DIRECTIVES, Validator, Validators, disableDeprecatedForms, provideForms} from '@angular/forms'; +import {ControlValueAccessor, FORM_DIRECTIVES, FORM_PROVIDERS, FormArray, FormControl, FormGroup, FormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, NgForm, NgModel, REACTIVE_FORM_DIRECTIVES, ReactiveFormsModule, Validator, Validators} from '@angular/forms'; import {By} from '@angular/platform-browser/src/dom/debug/by'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {dispatchEvent} from '@angular/platform-browser/testing/browser_util'; @@ -25,8 +24,8 @@ import {PromiseWrapper} from '../src/facade/promise'; export function main() { describe('integration tests', () => { - let providerArr: any[]; - beforeEach(() => { providerArr = [disableDeprecatedForms(), provideForms()]; }); + + beforeEach(() => { configureModule({modules: [FormsModule, ReactiveFormsModule]}); }); it('should initialize DOM elements with the given form object', inject( @@ -36,18 +35,15 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'login': new FormControl('loginValue')}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'login': new FormControl('loginValue')}); + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('loginValue'); - async.done(); - }); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('loginValue'); + async.done(); + }); })); it('should throw if a form isn\'t passed into formGroup', @@ -58,14 +54,11 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - expect(() => fixture.detectChanges()) - .toThrowError(new RegExp(`formGroup expects a FormGroup instance`)); - async.done(); - }); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + expect(() => fixture.detectChanges()) + .toThrowError(new RegExp(`formGroup expects a FormGroup instance`)); + async.done(); + }); })); it('should update the form group values on DOM change', @@ -78,20 +71,17 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); + var input = fixture.debugElement.query(By.css('input')); - input.nativeElement.value = 'updatedValue'; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = 'updatedValue'; + dispatchEvent(input.nativeElement, 'input'); - expect(form.value).toEqual({'login': 'updatedValue'}); - async.done(); - }); + expect(form.value).toEqual({'login': 'updatedValue'}); + async.done(); + }); })); it('should ignore the change event for ', @@ -104,22 +94,19 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); + var input = fixture.debugElement.query(By.css('input')); - input.nativeElement.value = 'updatedValue'; + input.nativeElement.value = 'updatedValue'; - ObservableWrapper.subscribe( - form.valueChanges, (value) => { throw 'Should not happen'; }); - dispatchEvent(input.nativeElement, 'change'); + ObservableWrapper.subscribe( + form.valueChanges, (value) => { throw 'Should not happen'; }); + dispatchEvent(input.nativeElement, 'change'); - async.done(); - }); + async.done(); + }); })); it('should emit ngSubmit event on submit', @@ -203,22 +190,19 @@ export function main() { const t = `
`; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = control; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = control; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('loginValue'); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('loginValue'); - input.nativeElement.value = 'updatedValue'; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = 'updatedValue'; + dispatchEvent(input.nativeElement, 'input'); - expect(control.value).toEqual('updatedValue'); - async.done(); - }); + expect(control.value).toEqual('updatedValue'); + async.done(); + }); })); it('should update DOM elements when rebinding the form group', @@ -229,22 +213,19 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'login': new FormControl('oldValue')}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'login': new FormControl('oldValue')}); + fixture.detectChanges(); - fixture.debugElement.componentInstance.form = - new FormGroup({'login': new FormControl('newValue')}); - fixture.detectChanges(); + fixture.debugElement.componentInstance.form = + new FormGroup({'login': new FormControl('newValue')}); + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('newValue'); - async.done(); - }); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('newValue'); + async.done(); + }); })); it('should update DOM elements when updating the value of a control', @@ -258,21 +239,18 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - login.updateValue('newValue'); + login.updateValue('newValue'); - fixture.detectChanges(); + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('newValue'); - async.done(); - }); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('newValue'); + async.done(); + }); })); it('should mark controls as touched after interacting with the DOM control', @@ -286,22 +264,19 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - var loginEl = fixture.debugElement.query(By.css('input')); - expect(login.touched).toBe(false); + var loginEl = fixture.debugElement.query(By.css('input')); + expect(login.touched).toBe(false); - dispatchEvent(loginEl.nativeElement, 'blur'); + dispatchEvent(loginEl.nativeElement, 'blur'); - expect(login.touched).toBe(true); + expect(login.touched).toBe(true); - async.done(); - }); + async.done(); + }); })); it('should support form arrays', @@ -317,29 +292,26 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.debugElement.componentInstance.cityArray = cityArray; - fixture.detectChanges(); - tick(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.debugElement.componentInstance.cityArray = cityArray; + fixture.detectChanges(); + tick(); - const inputs = fixture.debugElement.queryAll(By.css('input')); - expect(inputs[0].nativeElement.value).toEqual('SF'); - expect(inputs[1].nativeElement.value).toEqual('NY'); - expect(fixture.componentInstance.form.value).toEqual({cities: ['SF', 'NY']}); + const inputs = fixture.debugElement.queryAll(By.css('input')); + expect(inputs[0].nativeElement.value).toEqual('SF'); + expect(inputs[1].nativeElement.value).toEqual('NY'); + expect(fixture.componentInstance.form.value).toEqual({cities: ['SF', 'NY']}); - inputs[0].nativeElement.value = 'LA'; - dispatchEvent(inputs[0].nativeElement, 'input'); + inputs[0].nativeElement.value = 'LA'; + dispatchEvent(inputs[0].nativeElement, 'input'); - fixture.detectChanges(); - tick(); + fixture.detectChanges(); + tick(); - expect(fixture.componentInstance.form.value).toEqual({cities: ['LA', 'NY']}); + expect(fixture.componentInstance.form.value).toEqual({cities: ['LA', 'NY']}); - }); + }); }))); it('should support pushing new controls to form arrays', @@ -355,24 +327,21 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.debugElement.componentInstance.cityArray = cityArray; - fixture.detectChanges(); - tick(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.debugElement.componentInstance.cityArray = cityArray; + fixture.detectChanges(); + tick(); - cityArray.push(new FormControl('LA')); - fixture.detectChanges(); - tick(); + cityArray.push(new FormControl('LA')); + fixture.detectChanges(); + tick(); - const inputs = fixture.debugElement.queryAll(By.css('input')); - expect(inputs[2].nativeElement.value).toEqual('LA'); - expect(fixture.componentInstance.form.value).toEqual({cities: ['SF', 'NY', 'LA']}); + const inputs = fixture.debugElement.queryAll(By.css('input')); + expect(inputs[2].nativeElement.value).toEqual('LA'); + expect(fixture.componentInstance.form.value).toEqual({cities: ['SF', 'NY', 'LA']}); - }); + }); }))); describe('different control types', () => { @@ -384,25 +353,20 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'text': new FormControl('old')}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'text': new FormControl('old')}); + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('old'); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('old'); - input.nativeElement.value = 'new'; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = 'new'; + dispatchEvent(input.nativeElement, 'input'); - expect(fixture.debugElement.componentInstance.form.value).toEqual({ - 'text': 'new' - }); - async.done(); - }); + expect(fixture.debugElement.componentInstance.form.value).toEqual({'text': 'new'}); + async.done(); + }); })); it('should support without type', @@ -413,24 +377,19 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'text': new FormControl('old')}); - fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('old'); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'text': new FormControl('old')}); + fixture.detectChanges(); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('old'); - input.nativeElement.value = 'new'; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = 'new'; + dispatchEvent(input.nativeElement, 'input'); - expect(fixture.debugElement.componentInstance.form.value).toEqual({ - 'text': 'new' - }); - async.done(); - }); + expect(fixture.debugElement.componentInstance.form.value).toEqual({'text': 'new'}); + async.done(); + }); })); it('should support `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'text': new FormControl('old')}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'text': new FormControl('old')}); + fixture.detectChanges(); - var textarea = fixture.debugElement.query(By.css('textarea')); - expect(textarea.nativeElement.value).toEqual('old'); + var textarea = fixture.debugElement.query(By.css('textarea')); + expect(textarea.nativeElement.value).toEqual('old'); - textarea.nativeElement.value = 'new'; - dispatchEvent(textarea.nativeElement, 'input'); + textarea.nativeElement.value = 'new'; + dispatchEvent(textarea.nativeElement, 'input'); - expect(fixture.debugElement.componentInstance.form.value).toEqual({ - 'text': 'new' - }); - async.done(); - }); + expect(fixture.debugElement.componentInstance.form.value).toEqual({'text': 'new'}); + async.done(); + }); })); it('should support ', @@ -470,25 +424,22 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'checkbox': new FormControl(true)}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'checkbox': new FormControl(true)}); + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.checked).toBe(true); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.checked).toBe(true); - input.nativeElement.checked = false; - dispatchEvent(input.nativeElement, 'change'); + input.nativeElement.checked = false; + dispatchEvent(input.nativeElement, 'change'); - expect(fixture.debugElement.componentInstance.form.value).toEqual({ - 'checkbox': false - }); - async.done(); - }); + expect(fixture.debugElement.componentInstance.form.value).toEqual({ + 'checkbox': false + }); + async.done(); + }); })); it('should support ', @@ -499,23 +450,20 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'num': new FormControl(10)}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'num': new FormControl(10)}); + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('10'); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('10'); - input.nativeElement.value = '20'; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = '20'; + dispatchEvent(input.nativeElement, 'input'); - expect(fixture.debugElement.componentInstance.form.value).toEqual({'num': 20}); - async.done(); - }); + expect(fixture.debugElement.componentInstance.form.value).toEqual({'num': 20}); + async.done(); + }); })); it('should support when value is cleared in the UI', @@ -526,30 +474,25 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'num': new FormControl(10)}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'num': new FormControl(10)}); + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - input.nativeElement.value = ''; - dispatchEvent(input.nativeElement, 'input'); + var input = fixture.debugElement.query(By.css('input')); + input.nativeElement.value = ''; + dispatchEvent(input.nativeElement, 'input'); - expect(fixture.debugElement.componentInstance.form.valid).toBe(false); - expect(fixture.debugElement.componentInstance.form.value).toEqual({ - 'num': null - }); + expect(fixture.debugElement.componentInstance.form.valid).toBe(false); + expect(fixture.debugElement.componentInstance.form.value).toEqual({'num': null}); - input.nativeElement.value = '0'; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = '0'; + dispatchEvent(input.nativeElement, 'input'); - expect(fixture.debugElement.componentInstance.form.valid).toBe(true); - expect(fixture.debugElement.componentInstance.form.value).toEqual({'num': 0}); - async.done(); - }); + expect(fixture.debugElement.componentInstance.form.valid).toBe(true); + expect(fixture.debugElement.componentInstance.form.value).toEqual({'num': 0}); + async.done(); + }); })); @@ -562,19 +505,16 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.debugElement.componentInstance.data = null; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.debugElement.componentInstance.data = null; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual(''); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual(''); - async.done(); - }); + async.done(); + }); })); it('should support ', @@ -587,32 +527,29 @@ export function main() { `; const ctrl = new FormControl('fish'); - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = new FormGroup({'food': ctrl}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = new FormGroup({'food': ctrl}); + fixture.detectChanges(); - var inputs = fixture.debugElement.queryAll(By.css('input')); - expect(inputs[0].nativeElement.checked).toEqual(false); - expect(inputs[1].nativeElement.checked).toEqual(true); + var inputs = fixture.debugElement.queryAll(By.css('input')); + expect(inputs[0].nativeElement.checked).toEqual(false); + expect(inputs[1].nativeElement.checked).toEqual(true); - dispatchEvent(inputs[0].nativeElement, 'change'); - fixture.detectChanges(); + dispatchEvent(inputs[0].nativeElement, 'change'); + fixture.detectChanges(); - let value = fixture.debugElement.componentInstance.form.value; - expect(value.food).toEqual('chicken'); - expect(inputs[1].nativeElement.checked).toEqual(false); + let value = fixture.debugElement.componentInstance.form.value; + expect(value.food).toEqual('chicken'); + expect(inputs[1].nativeElement.checked).toEqual(false); - ctrl.updateValue('fish'); - fixture.detectChanges(); + ctrl.updateValue('fish'); + fixture.detectChanges(); - expect(inputs[0].nativeElement.checked).toEqual(false); - expect(inputs[1].nativeElement.checked).toEqual(true); + expect(inputs[0].nativeElement.checked).toEqual(false); + expect(inputs[1].nativeElement.checked).toEqual(true); - async.done(); - }); + async.done(); + }); })); it('should use formControlName to group radio buttons when name is absent', @@ -628,40 +565,37 @@ export function main() { const foodCtrl = new FormControl('fish'); const drinkCtrl = new FormControl('sprite'); - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'food': foodCtrl, 'drink': drinkCtrl}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'food': foodCtrl, 'drink': drinkCtrl}); + fixture.detectChanges(); - const inputs = fixture.debugElement.queryAll(By.css('input')); - expect(inputs[0].nativeElement.checked).toEqual(false); - expect(inputs[1].nativeElement.checked).toEqual(true); - expect(inputs[2].nativeElement.checked).toEqual(false); - expect(inputs[3].nativeElement.checked).toEqual(true); + const inputs = fixture.debugElement.queryAll(By.css('input')); + expect(inputs[0].nativeElement.checked).toEqual(false); + expect(inputs[1].nativeElement.checked).toEqual(true); + expect(inputs[2].nativeElement.checked).toEqual(false); + expect(inputs[3].nativeElement.checked).toEqual(true); - dispatchEvent(inputs[0].nativeElement, 'change'); - inputs[0].nativeElement.checked = true; - fixture.detectChanges(); + dispatchEvent(inputs[0].nativeElement, 'change'); + inputs[0].nativeElement.checked = true; + fixture.detectChanges(); - const value = fixture.debugElement.componentInstance.form.value; - expect(value.food).toEqual('chicken'); - expect(inputs[1].nativeElement.checked).toEqual(false); - expect(inputs[2].nativeElement.checked).toEqual(false); - expect(inputs[3].nativeElement.checked).toEqual(true); + const value = fixture.debugElement.componentInstance.form.value; + expect(value.food).toEqual('chicken'); + expect(inputs[1].nativeElement.checked).toEqual(false); + expect(inputs[2].nativeElement.checked).toEqual(false); + expect(inputs[3].nativeElement.checked).toEqual(true); - drinkCtrl.updateValue('cola'); - fixture.detectChanges(); + drinkCtrl.updateValue('cola'); + fixture.detectChanges(); - expect(inputs[0].nativeElement.checked).toEqual(true); - expect(inputs[1].nativeElement.checked).toEqual(false); - expect(inputs[2].nativeElement.checked).toEqual(true); - expect(inputs[3].nativeElement.checked).toEqual(false); + expect(inputs[0].nativeElement.checked).toEqual(true); + expect(inputs[1].nativeElement.checked).toEqual(false); + expect(inputs[2].nativeElement.checked).toEqual(true); + expect(inputs[3].nativeElement.checked).toEqual(false); - async.done(); - }); + async.done(); + }); })); it('should throw if radio button name does not match formControlName attr', @@ -672,17 +606,13 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'food': new FormControl('fish')}); - expect(() => fixture.detectChanges()) - .toThrowError( - new RegExp('If you define both a name and a formControlName')); - async.done(); - }); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'food': new FormControl('fish')}); + expect(() => fixture.detectChanges()) + .toThrowError(new RegExp('If you define both a name and a formControlName')); + async.done(); + }); })); it('should support removing controls from ', @@ -703,25 +633,22 @@ export function main() { const showRadio = new FormControl('yes'); const form = new FormGroup({'food': ctrl}); - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.debugElement.componentInstance.showRadio = showRadio; - showRadio.valueChanges.subscribe((change) => { - (change === 'yes') ? form.addControl('food', new FormControl('fish')) : - form.removeControl('food'); - }); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.debugElement.componentInstance.showRadio = showRadio; + showRadio.valueChanges.subscribe((change) => { + (change === 'yes') ? form.addControl('food', new FormControl('fish')) : + form.removeControl('food'); + }); + fixture.detectChanges(); - const input = fixture.debugElement.query(By.css('[value="no"]')); - dispatchEvent(input.nativeElement, 'change'); + const input = fixture.debugElement.query(By.css('[value="no"]')); + dispatchEvent(input.nativeElement, 'change'); - fixture.detectChanges(); - expect(form.value).toEqual({}); - async.done(); - }); + fixture.detectChanges(); + expect(form.value).toEqual({}); + async.done(); + }); })); describe('should support `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.detectChanges(); - var select = fixture.debugElement.query(By.css('select')); - var sfOption = fixture.debugElement.query(By.css('option')); + var select = fixture.debugElement.query(By.css('select')); + var sfOption = fixture.debugElement.query(By.css('option')); - expect(select.nativeElement.value).toEqual('SF'); - expect(sfOption.nativeElement.selected).toBe(true); - async.done(); - }); + expect(select.nativeElement.value).toEqual('SF'); + expect(sfOption.nativeElement.selected).toBe(true); + async.done(); + }); })); it('with basic selection and value bindings', @@ -759,22 +683,19 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - var testComp = fixture.debugElement.componentInstance; - testComp.list = [{'id': '0', 'name': 'SF'}, {'id': '1', 'name': 'NYC'}]; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + var testComp = fixture.debugElement.componentInstance; + testComp.list = [{'id': '0', 'name': 'SF'}, {'id': '1', 'name': 'NYC'}]; + fixture.detectChanges(); - var sfOption = fixture.debugElement.query(By.css('option')); - expect(sfOption.nativeElement.value).toEqual('0'); + var sfOption = fixture.debugElement.query(By.css('option')); + expect(sfOption.nativeElement.value).toEqual('0'); - testComp.list[0]['id'] = '2'; - fixture.detectChanges(); - expect(sfOption.nativeElement.value).toEqual('2'); - async.done(); - }); + testComp.list[0]['id'] = '2'; + fixture.detectChanges(); + expect(sfOption.nativeElement.value).toEqual('2'); + async.done(); + }); })); it('with ngControl', @@ -788,30 +709,27 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'city': new FormControl('SF')}); - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'city': new FormControl('SF')}); + fixture.detectChanges(); - var select = fixture.debugElement.query(By.css('select')); - var sfOption = fixture.debugElement.query(By.css('option')); + var select = fixture.debugElement.query(By.css('select')); + var sfOption = fixture.debugElement.query(By.css('option')); - expect(select.nativeElement.value).toEqual('SF'); - expect(sfOption.nativeElement.selected).toBe(true); + expect(select.nativeElement.value).toEqual('SF'); + expect(sfOption.nativeElement.selected).toBe(true); - select.nativeElement.value = 'NYC'; - dispatchEvent(select.nativeElement, 'change'); + select.nativeElement.value = 'NYC'; + dispatchEvent(select.nativeElement, 'change'); - expect(fixture.debugElement.componentInstance.form.value).toEqual({ - 'city': 'NYC' - }); - expect(sfOption.nativeElement.selected).toBe(false); - async.done(); - }); + expect(fixture.debugElement.componentInstance.form.value).toEqual({ + 'city': 'NYC' + }); + expect(sfOption.nativeElement.selected).toBe(false); + async.done(); + }); })); it('with a dynamic list of options', @@ -847,29 +765,26 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { - var testComp = fixture.debugElement.componentInstance; - testComp.list = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}]; - testComp.selectedCity = testComp.list[1]; - fixture.detectChanges(); + var testComp = fixture.debugElement.componentInstance; + testComp.list = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}]; + testComp.selectedCity = testComp.list[1]; + fixture.detectChanges(); - var select = fixture.debugElement.query(By.css('select')); - var nycOption = fixture.debugElement.queryAll(By.css('option'))[1]; + var select = fixture.debugElement.query(By.css('select')); + var nycOption = fixture.debugElement.queryAll(By.css('option'))[1]; - tick(); - expect(select.nativeElement.value).toEqual('1: Object'); - expect(nycOption.nativeElement.selected).toBe(true); + tick(); + expect(select.nativeElement.value).toEqual('1: Object'); + expect(nycOption.nativeElement.selected).toBe(true); - select.nativeElement.value = '2: Object'; - dispatchEvent(select.nativeElement, 'change'); - fixture.detectChanges(); - tick(); - expect(testComp.selectedCity['name']).toEqual('Buffalo'); - }); + select.nativeElement.value = '2: Object'; + dispatchEvent(select.nativeElement, 'change'); + fixture.detectChanges(); + tick(); + expect(testComp.selectedCity['name']).toEqual('Buffalo'); + }); }))); it('when new options are added (selection through the model)', @@ -880,26 +795,23 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { - var testComp: MyComp8 = fixture.debugElement.componentInstance; - testComp.list = [{'name': 'SF'}, {'name': 'NYC'}]; - testComp.selectedCity = testComp.list[1]; - fixture.detectChanges(); + var testComp: MyComp8 = fixture.debugElement.componentInstance; + testComp.list = [{'name': 'SF'}, {'name': 'NYC'}]; + testComp.selectedCity = testComp.list[1]; + fixture.detectChanges(); - testComp.list.push({'name': 'Buffalo'}); - testComp.selectedCity = testComp.list[2]; - fixture.detectChanges(); - tick(); + testComp.list.push({'name': 'Buffalo'}); + testComp.selectedCity = testComp.list[2]; + fixture.detectChanges(); + tick(); - var select = fixture.debugElement.query(By.css('select')); - var buffalo = fixture.debugElement.queryAll(By.css('option'))[2]; - expect(select.nativeElement.value).toEqual('2: Object'); - expect(buffalo.nativeElement.selected).toBe(true); - }); + var select = fixture.debugElement.query(By.css('select')); + var buffalo = fixture.debugElement.queryAll(By.css('option'))[2]; + expect(select.nativeElement.value).toEqual('2: Object'); + expect(buffalo.nativeElement.selected).toBe(true); + }); }))); it('when new options are added (selection through the UI)', @@ -912,28 +824,25 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { - var testComp: MyComp8 = fixture.debugElement.componentInstance; - testComp.list = [{'name': 'SF'}, {'name': 'NYC'}]; - testComp.selectedCity = testComp.list[0]; - fixture.detectChanges(); + var testComp: MyComp8 = fixture.debugElement.componentInstance; + testComp.list = [{'name': 'SF'}, {'name': 'NYC'}]; + testComp.selectedCity = testComp.list[0]; + fixture.detectChanges(); - var select = fixture.debugElement.query(By.css('select')); - var ny = fixture.debugElement.queryAll(By.css('option'))[1]; + var select = fixture.debugElement.query(By.css('select')); + var ny = fixture.debugElement.queryAll(By.css('option'))[1]; - select.nativeElement.value = '1: Object'; - dispatchEvent(select.nativeElement, 'change'); - testComp.list.push({'name': 'Buffalo'}); - fixture.detectChanges(); + select.nativeElement.value = '1: Object'; + dispatchEvent(select.nativeElement, 'change'); + testComp.list.push({'name': 'Buffalo'}); + fixture.detectChanges(); - expect(select.nativeElement.value).toEqual('1: Object'); - expect(ny.nativeElement.selected).toBe(true); - async.done(); - }); + expect(select.nativeElement.value).toEqual('1: Object'); + expect(ny.nativeElement.selected).toBe(true); + async.done(); + }); })); @@ -944,26 +853,23 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { - var testComp: MyComp8 = fixture.debugElement.componentInstance; - testComp.list = [{'name': 'SF'}, {'name': 'NYC'}]; - testComp.selectedCity = testComp.list[1]; - fixture.detectChanges(); - tick(); + var testComp: MyComp8 = fixture.debugElement.componentInstance; + testComp.list = [{'name': 'SF'}, {'name': 'NYC'}]; + testComp.selectedCity = testComp.list[1]; + fixture.detectChanges(); + tick(); - var select = fixture.debugElement.query(By.css('select')); - expect(select.nativeElement.value).toEqual('1: Object'); + var select = fixture.debugElement.query(By.css('select')); + expect(select.nativeElement.value).toEqual('1: Object'); - testComp.list.pop(); - fixture.detectChanges(); - tick(); + testComp.list.pop(); + fixture.detectChanges(); + tick(); - expect(select.nativeElement.value).not.toEqual('1: Object'); - }); + expect(select.nativeElement.value).not.toEqual('1: Object'); + }); }))); it('when option values change identity while tracking by index', @@ -974,28 +880,25 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { - var testComp = fixture.debugElement.componentInstance; + var testComp = fixture.debugElement.componentInstance; - testComp.list = [{'name': 'SF'}, {'name': 'NYC'}]; - testComp.selectedCity = testComp.list[0]; - fixture.detectChanges(); + testComp.list = [{'name': 'SF'}, {'name': 'NYC'}]; + testComp.selectedCity = testComp.list[0]; + fixture.detectChanges(); - testComp.list[1] = 'Buffalo'; - testComp.selectedCity = testComp.list[1]; - fixture.detectChanges(); - tick(); + testComp.list[1] = 'Buffalo'; + testComp.selectedCity = testComp.list[1]; + fixture.detectChanges(); + tick(); - var select = fixture.debugElement.query(By.css('select')); - var buffalo = fixture.debugElement.queryAll(By.css('option'))[1]; + var select = fixture.debugElement.query(By.css('select')); + var buffalo = fixture.debugElement.queryAll(By.css('option'))[1]; - expect(select.nativeElement.value).toEqual('1: Buffalo'); - expect(buffalo.nativeElement.selected).toBe(true); - }); + expect(select.nativeElement.value).toEqual('1: Buffalo'); + expect(buffalo.nativeElement.selected).toBe(true); + }); }))); it('with duplicate option values', @@ -1006,60 +909,52 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { - var testComp = fixture.debugElement.componentInstance; + var testComp = fixture.debugElement.componentInstance; - testComp.list = [{'name': 'NYC'}, {'name': 'SF'}, {'name': 'SF'}]; - testComp.selectedCity = testComp.list[0]; - fixture.detectChanges(); + testComp.list = [{'name': 'NYC'}, {'name': 'SF'}, {'name': 'SF'}]; + testComp.selectedCity = testComp.list[0]; + fixture.detectChanges(); - testComp.selectedCity = testComp.list[1]; - fixture.detectChanges(); - tick(); + testComp.selectedCity = testComp.list[1]; + fixture.detectChanges(); + tick(); - var select = fixture.debugElement.query(By.css('select')); - var firstSF = fixture.debugElement.queryAll(By.css('option'))[1]; + var select = fixture.debugElement.query(By.css('select')); + var firstSF = fixture.debugElement.queryAll(By.css('option'))[1]; - expect(select.nativeElement.value).toEqual('1: Object'); - expect(firstSF.nativeElement.selected).toBe(true); - }); + expect(select.nativeElement.value).toEqual('1: Object'); + expect(firstSF.nativeElement.selected).toBe(true); + }); }))); it('when option values have same content, but different identities', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - const t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + const t = `
`; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { - var testComp = fixture.debugElement.componentInstance; - testComp.list = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'NYC'}]; - testComp.selectedCity = testComp.list[0]; - fixture.detectChanges(); + var testComp = fixture.debugElement.componentInstance; + testComp.list = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'NYC'}]; + testComp.selectedCity = testComp.list[0]; + fixture.detectChanges(); - testComp.selectedCity = testComp.list[2]; - fixture.detectChanges(); + testComp.selectedCity = testComp.list[2]; + fixture.detectChanges(); + tick(); - var select = fixture.debugElement.query(By.css('select')); - var secondNYC = fixture.debugElement.queryAll(By.css('option'))[2]; + var select = fixture.debugElement.query(By.css('select')); + var secondNYC = fixture.debugElement.queryAll(By.css('option'))[2]; - expect(select.nativeElement.value).toEqual('2: Object'); - expect(secondNYC.nativeElement.selected).toBe(true); - async.done(); - }); - })); + expect(select.nativeElement.value).toEqual('2: Object'); + expect(secondNYC.nativeElement.selected).toBe(true); + }); + }))); }); it('should support custom value accessors', @@ -1070,24 +965,19 @@ export function main() {
`; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'name': new FormControl('aa')}); - fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('!aa!'); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'name': new FormControl('aa')}); + fixture.detectChanges(); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('!aa!'); - input.nativeElement.value = '!bb!'; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = '!bb!'; + dispatchEvent(input.nativeElement, 'input'); - expect(fixture.debugElement.componentInstance.form.value).toEqual({ - 'name': 'bb' - }); - async.done(); - }); + expect(fixture.debugElement.componentInstance.form.value).toEqual({'name': 'bb'}); + async.done(); + }); })); it('should support custom value accessors on non builtin input elements that fire a change event without a \'target\' property', @@ -1098,25 +988,22 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = - new FormGroup({'name': new FormControl('aa')}); - fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('my-input')); - expect(input.componentInstance.value).toEqual('!aa!'); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = + new FormGroup({'name': new FormControl('aa')}); + fixture.detectChanges(); + var input = fixture.debugElement.query(By.css('my-input')); + expect(input.componentInstance.value).toEqual('!aa!'); - input.componentInstance.value = '!bb!'; - ObservableWrapper.subscribe(input.componentInstance.onInput, (value) => { - expect(fixture.debugElement.componentInstance.form.value).toEqual({ - 'name': 'bb' - }); - async.done(); - }); - input.componentInstance.dispatchChangeEvent(); + input.componentInstance.value = '!bb!'; + ObservableWrapper.subscribe(input.componentInstance.onInput, (value) => { + expect(fixture.debugElement.componentInstance.form.value).toEqual({ + 'name': 'bb' }); + async.done(); + }); + input.componentInstance.dispatchChangeEvent(); + }); })); }); @@ -1138,41 +1025,38 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - var required = fixture.debugElement.query(By.css('[required]')); - var minLength = fixture.debugElement.query(By.css('[minlength]')); - var maxLength = fixture.debugElement.query(By.css('[maxlength]')); + var required = fixture.debugElement.query(By.css('[required]')); + var minLength = fixture.debugElement.query(By.css('[minlength]')); + var maxLength = fixture.debugElement.query(By.css('[maxlength]')); - required.nativeElement.value = ''; - minLength.nativeElement.value = '1'; - maxLength.nativeElement.value = '1234'; - dispatchEvent(required.nativeElement, 'input'); - dispatchEvent(minLength.nativeElement, 'input'); - dispatchEvent(maxLength.nativeElement, 'input'); + required.nativeElement.value = ''; + minLength.nativeElement.value = '1'; + maxLength.nativeElement.value = '1234'; + dispatchEvent(required.nativeElement, 'input'); + dispatchEvent(minLength.nativeElement, 'input'); + dispatchEvent(maxLength.nativeElement, 'input'); - expect(form.hasError('required', ['login'])).toEqual(true); - expect(form.hasError('minlength', ['min'])).toEqual(true); - expect(form.hasError('maxlength', ['max'])).toEqual(true); + expect(form.hasError('required', ['login'])).toEqual(true); + expect(form.hasError('minlength', ['min'])).toEqual(true); + expect(form.hasError('maxlength', ['max'])).toEqual(true); - expect(form.hasError('loginIsEmpty')).toEqual(true); + expect(form.hasError('loginIsEmpty')).toEqual(true); - required.nativeElement.value = '1'; - minLength.nativeElement.value = '123'; - maxLength.nativeElement.value = '123'; - dispatchEvent(required.nativeElement, 'input'); - dispatchEvent(minLength.nativeElement, 'input'); - dispatchEvent(maxLength.nativeElement, 'input'); + required.nativeElement.value = '1'; + minLength.nativeElement.value = '123'; + maxLength.nativeElement.value = '123'; + dispatchEvent(required.nativeElement, 'input'); + dispatchEvent(minLength.nativeElement, 'input'); + dispatchEvent(maxLength.nativeElement, 'input'); - expect(form.valid).toEqual(true); + expect(form.valid).toEqual(true); - async.done(); - }); + async.done(); + }); })); it('should use async validators defined in the html', @@ -1214,22 +1098,19 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); - expect(form.valid).toEqual(true); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); + expect(form.valid).toEqual(true); - var input = fixture.debugElement.query(By.css('input')); + var input = fixture.debugElement.query(By.css('input')); - input.nativeElement.value = ''; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = ''; + dispatchEvent(input.nativeElement, 'input'); - expect(form.valid).toEqual(false); - async.done(); - }); + expect(form.valid).toEqual(false); + async.done(); + }); })); it('should use async validators defined in the model', @@ -1282,17 +1163,14 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.value).toEqual('value'); - async.done(); - }); + var input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.value).toEqual('value'); + async.done(); + }); })); it('should update the control group values on DOM change', @@ -1308,20 +1186,17 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); + var input = fixture.debugElement.query(By.css('input')); - input.nativeElement.value = 'updatedValue'; - dispatchEvent(input.nativeElement, 'input'); + input.nativeElement.value = 'updatedValue'; + dispatchEvent(input.nativeElement, 'input'); - expect(form.value).toEqual({'nested': {'login': 'updatedValue'}}); - async.done(); - }); + expect(form.value).toEqual({'nested': {'login': 'updatedValue'}}); + async.done(); + }); })); }); @@ -1445,16 +1320,13 @@ export function main() { const t = `
`; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.name = null; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.name = null; + fixture.detectChanges(); - expect(fixture.debugElement.children[0].providerTokens.length).toEqual(0); - async.done(); - }); + expect(fixture.debugElement.children[0].providerTokens.length).toEqual(0); + async.done(); + }); })); it('should remove controls', @@ -1580,14 +1452,11 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - expect(() => fixture.detectChanges()) - .toThrowError(new RegExp(`name attribute must be set`)); - async.done(); - }); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + expect(() => fixture.detectChanges()) + .toThrowError(new RegExp(`name attribute must be set`)); + async.done(); + }); })); it('should not throw if ngModel has a parent form, no name attr, and a standalone label', @@ -1598,13 +1467,10 @@ export function main() { `; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - expect(() => fixture.detectChanges()).not.toThrow(); - async.done(); - }); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + expect(() => fixture.detectChanges()).not.toThrow(); + async.done(); + }); })); @@ -1723,32 +1589,29 @@ export function main() { const t = `
`; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual([ - 'ng-invalid', 'ng-pristine', 'ng-untouched' - ]); + var input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-untouched' + ]); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual([ - 'ng-invalid', 'ng-pristine', 'ng-touched' - ]); + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-touched' + ]); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - async.done(); - }); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + async.done(); + }); })); it('should work with complex model-driven forms', @@ -1760,32 +1623,29 @@ export function main() { const t = `
`; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual([ - 'ng-invalid', 'ng-pristine', 'ng-untouched' - ]); + var input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-untouched' + ]); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual([ - 'ng-invalid', 'ng-pristine', 'ng-touched' - ]); + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-touched' + ]); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - async.done(); - }); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + async.done(); + }); })); it('should work with ngModel', @@ -1794,32 +1654,29 @@ export function main() { (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { const t = `
`; - tcb.overrideTemplate(MyComp8, t) - .overrideProviders(MyComp8, providerArr) - .createAsync(MyComp8) - .then((fixture) => { - fixture.debugElement.componentInstance.name = ''; - fixture.detectChanges(); + tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => { + fixture.debugElement.componentInstance.name = ''; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual([ - 'ng-invalid', 'ng-pristine', 'ng-untouched' - ]); + var input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-untouched' + ]); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual([ - 'ng-invalid', 'ng-pristine', 'ng-touched' - ]); + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-touched' + ]); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - async.done(); - }); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + async.done(); + }); })); }); @@ -1860,20 +1717,20 @@ export function main() { input.selectionStart = 1; dispatchEvent(input, 'input'); - tick(); fixture.detectChanges(); + tick(); expect(fixture.debugElement.componentInstance.name).toEqual('aa'); - // Programatically update the input value to be "bb". + // Programmatically update the input value to be "bb". fixture.debugElement.componentInstance.name = 'bb'; - tick(); fixture.detectChanges(); + tick(); expect(input.value).toEqual('bb'); // Programatically set it back to "aa". fixture.debugElement.componentInstance.name = 'aa'; - tick(); fixture.detectChanges(); + tick(); expect(input.value).toEqual('aa'); }))); it('should not crash when validity is checked from a binding', @@ -1972,11 +1829,7 @@ class UniqLoginValidator implements Validator { @Component({ selector: 'my-comp', template: '', - directives: [ - FORM_DIRECTIVES, WrappedValue, MyInput, NgIf, NgFor, LoginIsEmptyValidator, UniqLoginValidator, - REACTIVE_FORM_DIRECTIVES - ], - providers: [FORM_PROVIDERS] + directives: [WrappedValue, MyInput, NgIf, NgFor, LoginIsEmptyValidator, UniqLoginValidator] }) class MyComp8 { form: any; diff --git a/modules/@angular/platform-browser/src/browser.ts b/modules/@angular/platform-browser/src/browser.ts index ad2da207b5..e52af7bd95 100644 --- a/modules/@angular/platform-browser/src/browser.ts +++ b/modules/@angular/platform-browser/src/browser.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS, PlatformLocation} from '@angular/common'; +import {COMMON_DIRECTIVES, COMMON_PIPES, PlatformLocation} from '@angular/common'; import {APPLICATION_COMMON_PROVIDERS, AppModule, AppModuleFactory, AppModuleRef, ExceptionHandler, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, SanitizationService, Testability, assertPlatform, createPlatform, getPlatform, isDevMode} from '@angular/core'; import {wtfInit} from '../core_private'; @@ -62,7 +62,7 @@ export const BROWSER_SANITIZATION_PROVIDERS: Array = [ * @experimental API related to bootstrapping are still under review. */ export const BROWSER_APP_PROVIDERS: Array = [ - APPLICATION_COMMON_PROVIDERS, FORM_PROVIDERS, BROWSER_SANITIZATION_PROVIDERS, + APPLICATION_COMMON_PROVIDERS, BROWSER_SANITIZATION_PROVIDERS, {provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []}, {provide: DOCUMENT, useFactory: _document, deps: []}, {provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true}, diff --git a/tools/public_api_guard/common/index.d.ts b/tools/public_api_guard/common/index.d.ts index 2af6131cf1..ea7228ad2b 100644 --- a/tools/public_api_guard/common/index.d.ts +++ b/tools/public_api_guard/common/index.d.ts @@ -162,6 +162,10 @@ export declare class DefaultValueAccessor implements ControlValueAccessor { writeValue(value: any): void; } +/** @deprecated */ +export declare class DeprecatedFormsModule { +} + /** @experimental */ export interface Form { addControl(dir: NgControl): void; diff --git a/tools/public_api_guard/forms/index.d.ts b/tools/public_api_guard/forms/index.d.ts index e9c4b3a30e..2cc79916ee 100644 --- a/tools/public_api_guard/forms/index.d.ts +++ b/tools/public_api_guard/forms/index.d.ts @@ -101,9 +101,6 @@ export declare class DefaultValueAccessor implements ControlValueAccessor { writeValue(value: any): void; } -/** @experimental */ -export declare function disableDeprecatedForms(): any[]; - /** @experimental */ export interface Form { addControl(dir: NgControl): void; @@ -116,7 +113,7 @@ export interface Form { } /** @experimental */ -export declare const FORM_DIRECTIVES: Type[]; +export declare const FORM_DIRECTIVES: Type[][]; /** @experimental */ export declare const FORM_PROVIDERS: Type[]; @@ -246,6 +243,10 @@ export declare class FormGroupName extends AbstractFormGroupDirective implements constructor(parent: ControlContainer, validators: any[], asyncValidators: any[]); } +/** @experimental */ +export declare class FormsModule { +} + /** @experimental */ export declare class MaxLengthValidator implements Validator { constructor(maxLength: string); @@ -358,10 +359,14 @@ export declare class PatternValidator implements Validator { } /** @experimental */ -export declare function provideForms(): any[]; +export declare const REACTIVE_FORM_DIRECTIVES: Type[][]; /** @experimental */ -export declare const REACTIVE_FORM_DIRECTIVES: Type[]; +export declare const REACTIVE_FORM_PROVIDERS: Type[]; + +/** @experimental */ +export declare class ReactiveFormsModule { +} /** @experimental */ export declare class RequiredValidator {