From e1fcab777c62b063d78543098a3229d5abbd10a0 Mon Sep 17 00:00:00 2001 From: Rob Wormald Date: Thu, 9 Jun 2016 22:52:30 -0700 Subject: [PATCH] fix(ngSwitch): use switchCase instead of switchWhen (#9076) --- modules/@angular/common/src/directives.ts | 2 +- .../common/src/directives/core_directives.ts | 5 +- .../common/src/directives/ng_switch.ts | 72 +++++++++++-------- .../common/test/directives/ng_switch_spec.ts | 47 +++++++++--- tools/public_api_guard/public_api_spec.ts | 7 +- 5 files changed, 88 insertions(+), 45 deletions(-) diff --git a/modules/@angular/common/src/directives.ts b/modules/@angular/common/src/directives.ts index c5af208965..dd07edfb27 100644 --- a/modules/@angular/common/src/directives.ts +++ b/modules/@angular/common/src/directives.ts @@ -9,5 +9,5 @@ export {NgFor} from './directives/ng_for'; export {NgIf} from './directives/ng_if'; export {NgLocalization, NgPlural, NgPluralCase} from './directives/ng_plural'; export {NgStyle} from './directives/ng_style'; -export {NgSwitch, NgSwitchDefault, NgSwitchWhen} from './directives/ng_switch'; +export {NgSwitch, NgSwitchCase, NgSwitchDefault} from './directives/ng_switch'; export {NgTemplateOutlet} from './directives/ng_template_outlet'; diff --git a/modules/@angular/common/src/directives/core_directives.ts b/modules/@angular/common/src/directives/core_directives.ts index a40ea36785..29110ff781 100644 --- a/modules/@angular/common/src/directives/core_directives.ts +++ b/modules/@angular/common/src/directives/core_directives.ts @@ -5,10 +5,11 @@ import {NgFor} from './ng_for'; import {NgIf} from './ng_if'; import {NgPlural, NgPluralCase} from './ng_plural'; import {NgStyle} from './ng_style'; -import {NgSwitch, NgSwitchDefault, NgSwitchWhen} from './ng_switch'; +import {NgSwitch, NgSwitchCase, NgSwitchDefault} 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 * application. @@ -58,7 +59,7 @@ export const CORE_DIRECTIVES: Type[] = /*@ts2dart_const*/[ NgTemplateOutlet, NgStyle, NgSwitch, - NgSwitchWhen, + NgSwitchCase, NgSwitchDefault, NgPlural, NgPluralCase, diff --git a/modules/@angular/common/src/directives/ng_switch.ts b/modules/@angular/common/src/directives/ng_switch.ts index 0b2ae7cead..3a797e0b8c 100644 --- a/modules/@angular/common/src/directives/ng_switch.ts +++ b/modules/@angular/common/src/directives/ng_switch.ts @@ -3,7 +3,7 @@ import {Directive, Host, TemplateRef, ViewContainerRef} from '@angular/core'; import {ListWrapper, Map} from '../facade/collection'; import {isBlank, isPresent, normalizeBlank} from '../facade/lang'; -const _WHEN_DEFAULT = /*@ts2dart_const*/ new Object(); +const _CASE_DEFAULT = /*@ts2dart_const*/ new Object(); export class SwitchView { constructor( @@ -17,17 +17,17 @@ export class SwitchView { /** * Adds or removes DOM sub-trees when their match expressions match the switch expression. * - * Elements within `NgSwitch` but without `NgSwitchWhen` or `NgSwitchDefault` directives will be + * Elements within `NgSwitch` but without `ngSwitchCase` or `NgSwitchDefault` directives will be * preserved at the location as specified in the template. * * `NgSwitch` simply inserts nested elements based on which match expression matches the value * obtained from the evaluated switch expression. In other words, you define a container element * (where you place the directive with a switch expression on the * `[ngSwitch]="..."` attribute), define any inner elements inside of the directive and - * place a `[ngSwitchWhen]` attribute per element. + * place a `[ngSwitchCase]` attribute per element. * - * The `ngSwitchWhen` property is used to inform `NgSwitch` which element to display when the - * expression is evaluated. If a matching expression is not found via a `ngSwitchWhen` property + * The `ngSwitchCase` property is used to inform `NgSwitch` which element to display when the + * expression is evaluated. If a matching expression is not found via a `ngSwitchCase` property * then an element with the `ngSwitchDefault` attribute is displayed. * * ### Example ([live demo](http://plnkr.co/edit/DQMTII95CbuqWrl3lYAs?p=preview)) @@ -40,24 +40,24 @@ export class SwitchView { * * *
- *

increment to start

- *

0, increment again

- *

1, increment again

- *

2, stop incrementing

+ *

increment to start

+ *

0, increment again

+ *

1, increment again

+ *

2, stop incrementing

*

> 2, STOP!

*
* * * *

- * - * - * - * + * + * + * + * * *

* `, - * directives: [NgSwitch, NgSwitchWhen, NgSwitchDefault] + * directives: [NgSwitch, ngSwitchCase, NgSwitchDefault] * }) * export class App { * value = 'init'; @@ -88,7 +88,7 @@ export class NgSwitch { var views = this._valueViews.get(value); if (isBlank(views)) { this._useDefault = true; - views = normalizeBlank(this._valueViews.get(_WHEN_DEFAULT)); + views = normalizeBlank(this._valueViews.get(_CASE_DEFAULT)); } this._activateViews(views); @@ -96,14 +96,14 @@ export class NgSwitch { } /** @internal */ - _onWhenValueChanged(oldWhen: any, newWhen: any, view: SwitchView): void { - this._deregisterView(oldWhen, view); - this._registerView(newWhen, view); + _onCaseValueChanged(oldCase: any, newCase: any, view: SwitchView): void { + this._deregisterView(oldCase, view); + this._registerView(newCase, view); - if (oldWhen === this._switchValue) { + if (oldCase === this._switchValue) { view.destroy(); ListWrapper.remove(this._activeViews, view); - } else if (newWhen === this._switchValue) { + } else if (newCase === this._switchValue) { if (this._useDefault) { this._useDefault = false; this._emptyAllActiveViews(); @@ -115,7 +115,7 @@ export class NgSwitch { // Switch to default when there is no more active ViewContainers if (this._activeViews.length === 0 && !this._useDefault) { this._useDefault = true; - this._activateViews(this._valueViews.get(_WHEN_DEFAULT)); + this._activateViews(this._valueViews.get(_CASE_DEFAULT)); } } @@ -151,8 +151,8 @@ export class NgSwitch { /** @internal */ _deregisterView(value: any, view: SwitchView): void { - // `_WHEN_DEFAULT` is used a marker for non-registered whens - if (value === _WHEN_DEFAULT) return; + // `_CASE_DEFAULT` is used a marker for non-registered cases + if (value === _CASE_DEFAULT) return; var views = this._valueViews.get(value); if (views.length == 1) { this._valueViews.delete(value); @@ -163,7 +163,7 @@ export class NgSwitch { } /** - * Insert the sub-tree when the `ngSwitchWhen` expression evaluates to the same value as the + * Insert the sub-tree when the `ngSwitchCase` expression evaluates to the same value as the * enclosing switch expression. * * If multiple match expression match the switch expression value, all of them are displayed. @@ -172,13 +172,16 @@ export class NgSwitch { * * @experimental */ -@Directive({selector: '[ngSwitchWhen]', inputs: ['ngSwitchWhen']}) -export class NgSwitchWhen { - // `_WHEN_DEFAULT` is used as a marker for a not yet initialized value +@Directive({selector: '[ngSwitchCase],[ngSwitchWhen]', inputs: ['ngSwitchCase', 'ngSwitchWhen']}) +export class NgSwitchCase { + // `_CASE_DEFAULT` is used as a marker for a not yet initialized value /** @internal */ - _value: any = _WHEN_DEFAULT; + _value: any = _CASE_DEFAULT; /** @internal */ _view: SwitchView; + // TODO: remove when fully deprecated + /** @internal */ + _warned: boolean; private _switch: NgSwitch; constructor( @@ -188,8 +191,17 @@ export class NgSwitchWhen { this._view = new SwitchView(viewContainer, templateRef); } + set ngSwitchCase(value: any) { + this._switch._onCaseValueChanged(this._value, value, this._view); + this._value = value; + } + set ngSwitchWhen(value: any) { - this._switch._onWhenValueChanged(this._value, value, this._view); + if (!this._warned) { + this._warned = true; + console.warn('*ngSwitchWhen is deprecated and will be removed. Use *ngSwitchCase instead'); + } + this._switch._onCaseValueChanged(this._value, value, this._view); this._value = value; } } @@ -207,6 +219,6 @@ export class NgSwitchDefault { constructor( viewContainer: ViewContainerRef, templateRef: TemplateRef, @Host() sswitch: NgSwitch) { - sswitch._registerView(_WHEN_DEFAULT, new SwitchView(viewContainer, templateRef)); + sswitch._registerView(_CASE_DEFAULT, new SwitchView(viewContainer, templateRef)); } } diff --git a/modules/@angular/common/test/directives/ng_switch_spec.ts b/modules/@angular/common/test/directives/ng_switch_spec.ts index e2f637be13..e9a2ed69b8 100644 --- a/modules/@angular/common/test/directives/ng_switch_spec.ts +++ b/modules/@angular/common/test/directives/ng_switch_spec.ts @@ -3,12 +3,41 @@ import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; import {Component} from '@angular/core'; import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing'; -import {NgSwitch, NgSwitchWhen, NgSwitchDefault} from '@angular/common'; +import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common'; export function main() { describe('switch', () => { describe('switch value changes', () => { it('should switch amongst when values', + inject( + [TestComponentBuilder, AsyncTestCompleter], + (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { + var template = '
' + + '
    ' + + '' + + '' + + '
'; + + tcb.overrideTemplate(TestComponent, template) + .createAsync(TestComponent) + .then((fixture) => { + fixture.detectChanges(); + expect(fixture.debugElement.nativeElement).toHaveText(''); + + fixture.debugElement.componentInstance.switchValue = 'a'; + fixture.detectChanges(); + expect(fixture.debugElement.nativeElement).toHaveText('when a'); + + fixture.debugElement.componentInstance.switchValue = 'b'; + fixture.detectChanges(); + expect(fixture.debugElement.nativeElement).toHaveText('when b'); + + async.done(); + }); + })); + + // TODO(robwormald): deprecate and remove + it('should switch amongst when values using switchWhen', inject( [TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { @@ -42,7 +71,7 @@ export function main() { (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { var template = '
' + '
    ' + - '
  • when a
  • ' + + '
  • when a
  • ' + '
  • when default
  • ' + '
'; @@ -70,10 +99,10 @@ export function main() { (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { var template = '
' + '
    ' + - '' + - '' + - '' + - '' + + '' + + '' + + '' + + '' + '' + '' + '
'; @@ -105,8 +134,8 @@ export function main() { (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { var template = '
' + '
    ' + - '' + - '' + + '' + + '' + '' + '
'; @@ -143,7 +172,7 @@ export function main() { } @Component( - {selector: 'test-cmp', directives: [NgSwitch, NgSwitchWhen, NgSwitchDefault], template: ''}) + {selector: 'test-cmp', directives: [NgSwitch, NgSwitchCase, NgSwitchDefault], template: ''}) class TestComponent { switchValue: any; when1: any; diff --git a/tools/public_api_guard/public_api_spec.ts b/tools/public_api_guard/public_api_spec.ts index e4a3cc139c..d0ebd1d211 100644 --- a/tools/public_api_guard/public_api_spec.ts +++ b/tools/public_api_guard/public_api_spec.ts @@ -980,11 +980,12 @@ const COMMON = [ 'NgStyle.rawStyle=(v:{[key:string]:string})', 'NgSwitch', 'NgSwitch.ngSwitch=(value:any)', + 'NgSwitchCase', + 'NgSwitchCase.constructor(viewContainer:ViewContainerRef, templateRef:TemplateRef, ngSwitch:NgSwitch)', + 'NgSwitchCase.ngSwitchCase=(value:any)', + 'NgSwitchCase.ngSwitchWhen=(value:any)', 'NgSwitchDefault', 'NgSwitchDefault.constructor(viewContainer:ViewContainerRef, templateRef:TemplateRef, sswitch:NgSwitch)', - 'NgSwitchWhen', - 'NgSwitchWhen.constructor(viewContainer:ViewContainerRef, templateRef:TemplateRef, ngSwitch:NgSwitch)', - 'NgSwitchWhen.ngSwitchWhen=(value:any)', 'NgTemplateOutlet', 'NgTemplateOutlet.constructor(_viewContainerRef:ViewContainerRef)', 'NgTemplateOutlet.ngTemplateOutlet=(templateRef:TemplateRef)',