Skip to content

Commit b7e69bc

Browse files
authored
fix(NgPlural): expression inside cases (angular#9883)
fixes angular#9868
1 parent 72544ba commit b7e69bc

File tree

3 files changed

+42
-28
lines changed

3 files changed

+42
-28
lines changed

modules/@angular/common/src/directives/ng_plural.ts

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {AfterContentInit, Attribute, ContentChildren, Directive, Input, QueryList, TemplateRef, ViewContainerRef} from '@angular/core';
9+
import {Attribute, Directive, Host, Input, OnInit, TemplateRef, ViewContainerRef} from '@angular/core';
10+
1011
import {isPresent} from '../facade/lang';
1112
import {NgLocalization, getPluralCategory} from '../localization';
13+
1214
import {SwitchView} from './ng_switch';
1315

16+
1417
/**
1518
* `ngPlural` is an i18n directive that displays DOM sub-trees that match the switch expression
1619
* value, or failing that, DOM sub-trees that match the switch expression's pluralization category.
@@ -64,27 +67,11 @@ import {SwitchView} from './ng_switch';
6467
* ```
6568
* @experimental
6669
*/
67-
68-
@Directive({selector: '[ngPluralCase]'})
69-
export class NgPluralCase {
70-
/** @internal */
71-
_view: SwitchView;
72-
constructor(
73-
@Attribute('ngPluralCase') public value: string, template: TemplateRef<Object>,
74-
viewContainer: ViewContainerRef) {
75-
this._view = new SwitchView(viewContainer, template);
76-
}
77-
}
78-
79-
/**
80-
* @experimental
81-
*/
8270
@Directive({selector: '[ngPlural]'})
83-
export class NgPlural implements AfterContentInit {
71+
export class NgPlural {
8472
private _switchValue: number;
8573
private _activeView: SwitchView;
8674
private _caseViews: {[k: string]: SwitchView} = {};
87-
@ContentChildren(NgPluralCase) cases: QueryList<NgPluralCase> = null;
8875

8976
constructor(private _localization: NgLocalization) {}
9077

@@ -94,12 +81,7 @@ export class NgPlural implements AfterContentInit {
9481
this._updateView();
9582
}
9683

97-
ngAfterContentInit() {
98-
this.cases.forEach((pluralCase: NgPluralCase): void => {
99-
this._caseViews[pluralCase.value] = pluralCase._view;
100-
});
101-
this._updateView();
102-
}
84+
addCase(value: string, switchView: SwitchView): void { this._caseViews[value] = switchView; }
10385

10486
/** @internal */
10587
_updateView(): void {
@@ -122,3 +104,15 @@ export class NgPlural implements AfterContentInit {
122104
this._activeView.create();
123105
}
124106
}
107+
108+
/**
109+
* @experimental
110+
*/
111+
@Directive({selector: '[ngPluralCase]'})
112+
export class NgPluralCase {
113+
constructor(
114+
@Attribute('ngPluralCase') public value: string, template: TemplateRef<Object>,
115+
viewContainer: ViewContainerRef, @Host() ngPlural: NgPlural) {
116+
ngPlural.addCase(value, new SwitchView(viewContainer, template));
117+
}
118+
}

modules/@angular/common/test/directives/ng_plural_spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@ export function main() {
4242
});
4343
}));
4444

45+
// https://github.com/angular/angular/issues/9868
46+
// https://github.com/angular/angular/issues/9882
47+
it('should not throw when ngPluralCase contains expressions',
48+
inject(
49+
[TestComponentBuilder, AsyncTestCompleter],
50+
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
51+
var template = '<div>' +
52+
'<ul [ngPlural]="switchValue">' +
53+
'<template ngPluralCase="=0"><li>{{ switchValue }}</li></template>' +
54+
'</ul></div>';
55+
56+
tcb.overrideTemplate(TestComponent, template)
57+
.createAsync(TestComponent)
58+
.then((fixture) => {
59+
fixture.debugElement.componentInstance.switchValue = 0;
60+
expect(() => fixture.detectChanges()).not.toThrow();
61+
async.done();
62+
});
63+
}));
64+
65+
4566
it('should be applicable to <ng-container> elements',
4667
inject(
4768
[TestComponentBuilder, AsyncTestCompleter],

tools/public_api_guard/common/index.d.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,17 +437,16 @@ export declare class NgModel extends NgControl implements OnChanges {
437437
}
438438

439439
/** @experimental */
440-
export declare class NgPlural implements AfterContentInit {
441-
cases: QueryList<NgPluralCase>;
440+
export declare class NgPlural {
442441
ngPlural: number;
443442
constructor(_localization: NgLocalization);
444-
ngAfterContentInit(): void;
443+
addCase(value: string, switchView: SwitchView): void;
445444
}
446445

447446
/** @experimental */
448447
export declare class NgPluralCase {
449448
value: string;
450-
constructor(value: string, template: TemplateRef<Object>, viewContainer: ViewContainerRef);
449+
constructor(value: string, template: TemplateRef<Object>, viewContainer: ViewContainerRef, ngPlural: NgPlural);
451450
}
452451

453452
/** @experimental */

0 commit comments

Comments
 (0)