Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 82327f2

Browse filesBrowse files
rslawikatscott
authored andcommitted
feat(common): accept undefined inputs in NgTemplateOutlet (#61404)
Extend types of inputs to include `undefined` to avoid `?? null` when using singals (e.g. `viewChild`). Fixes #51225 PR Close #61404
1 parent d3e9ca1 commit 82327f2
Copy full SHA for 82327f2

File tree

Expand file treeCollapse file tree

3 files changed

+35
-6
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+35
-6
lines changed

‎goldens/public-api/common/index.api.md

Copy file name to clipboardExpand all lines: goldens/public-api/common/index.api.md
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -716,9 +716,9 @@ export class NgTemplateOutlet<C = unknown> implements OnChanges {
716716
constructor(_viewContainerRef: ViewContainerRef);
717717
// (undocumented)
718718
ngOnChanges(changes: SimpleChanges): void;
719-
ngTemplateOutlet: TemplateRef<C> | null;
720-
ngTemplateOutletContext: C | null;
721-
ngTemplateOutletInjector: Injector | null;
719+
ngTemplateOutlet: TemplateRef<C> | null | undefined;
720+
ngTemplateOutletContext: C | null | undefined;
721+
ngTemplateOutletInjector: Injector | null | undefined;
722722
// (undocumented)
723723
static ɵdir: i0.ɵɵDirectiveDeclaration<NgTemplateOutlet<any>, "[ngTemplateOutlet]", never, { "ngTemplateOutletContext": { "alias": "ngTemplateOutletContext"; "required": false; }; "ngTemplateOutlet": { "alias": "ngTemplateOutlet"; "required": false; }; "ngTemplateOutletInjector": { "alias": "ngTemplateOutletInjector"; "required": false; }; }, {}, never, never, true, never>;
724724
// (undocumented)

‎packages/common/src/directives/ng_template_outlet.ts

Copy file name to clipboardExpand all lines: packages/common/src/directives/ng_template_outlet.ts
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ export class NgTemplateOutlet<C = unknown> implements OnChanges {
5454
* declarations.
5555
* Using the key `$implicit` in the context object will set its value as default.
5656
*/
57-
@Input() public ngTemplateOutletContext: C | null = null;
57+
@Input() public ngTemplateOutletContext: C | null | undefined = null;
5858

5959
/**
6060
* A string defining the template reference and optionally the context object for the template.
6161
*/
62-
@Input() public ngTemplateOutlet: TemplateRef<C> | null = null;
62+
@Input() public ngTemplateOutlet: TemplateRef<C> | null | undefined = null;
6363

6464
/** Injector to be used within the embedded view. */
65-
@Input() public ngTemplateOutletInjector: Injector | null = null;
65+
@Input() public ngTemplateOutletInjector: Injector | null | undefined = null;
6666

6767
constructor(private _viewContainerRef: ViewContainerRef) {}
6868

‎packages/common/test/directives/ng_template_outlet_spec.ts

Copy file name to clipboardExpand all lines: packages/common/test/directives/ng_template_outlet_spec.ts
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ describe('NgTemplateOutlet', () => {
7070
detectChangesAndExpectText('');
7171
}));
7272

73+
it('should do nothing if templateRef is `undefined`', waitForAsync(() => {
74+
const template = `<ng-container [ngTemplateOutlet]="undefined"></ng-container>`;
75+
fixture = createTestComponent(template);
76+
detectChangesAndExpectText('');
77+
}));
78+
7379
it('should insert content specified by TemplateRef', waitForAsync(() => {
7480
const template =
7581
`<ng-template #tpl>foo</ng-template>` +
@@ -93,6 +99,21 @@ describe('NgTemplateOutlet', () => {
9399
detectChangesAndExpectText('');
94100
}));
95101

102+
it('should clear content if TemplateRef becomes `undefined`', waitForAsync(() => {
103+
const template =
104+
`<tpl-refs #refs="tplRefs"><ng-template>foo</ng-template></tpl-refs>` +
105+
`<ng-container [ngTemplateOutlet]="currentTplRef"></ng-container>`;
106+
fixture = createTestComponent(template);
107+
fixture.detectChanges();
108+
const refs = fixture.debugElement.children[0].references!['refs'];
109+
110+
setTplRef(refs.tplRefs.first);
111+
detectChangesAndExpectText('foo');
112+
113+
setTplRef(undefined);
114+
detectChangesAndExpectText('');
115+
}));
116+
96117
it('should swap content if TemplateRef changes', waitForAsync(() => {
97118
const template =
98119
`<tpl-refs #refs="tplRefs"><ng-template>foo</ng-template><ng-template>bar</ng-template></tpl-refs>` +
@@ -117,6 +138,14 @@ describe('NgTemplateOutlet', () => {
117138
detectChangesAndExpectText('foo');
118139
}));
119140

141+
it('should display template if context is `undefined`', waitForAsync(() => {
142+
const template =
143+
`<ng-template #tpl>foo</ng-template>` +
144+
`<ng-container *ngTemplateOutlet="tpl; context: undefined"></ng-container>`;
145+
fixture = createTestComponent(template);
146+
detectChangesAndExpectText('foo');
147+
}));
148+
120149
it('should reflect initial context and changes', waitForAsync(() => {
121150
const template =
122151
`<ng-template let-foo="foo" #tpl>{{foo}}</ng-template>` +

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.