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

feat(common): accept undefined inputs in NgTemplateOutlet #61404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions 6 goldens/public-api/common/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -716,9 +716,9 @@ export class NgTemplateOutlet<C = unknown> implements OnChanges {
constructor(_viewContainerRef: ViewContainerRef);
// (undocumented)
ngOnChanges(changes: SimpleChanges): void;
ngTemplateOutlet: TemplateRef<C> | null;
ngTemplateOutletContext: C | null;
ngTemplateOutletInjector: Injector | null;
ngTemplateOutlet: TemplateRef<C> | null | undefined;
ngTemplateOutletContext: C | null | undefined;
ngTemplateOutletInjector: Injector | null | undefined;
// (undocumented)
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>;
// (undocumented)
Expand Down
6 changes: 3 additions & 3 deletions 6 packages/common/src/directives/ng_template_outlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ export class NgTemplateOutlet<C = unknown> implements OnChanges {
* declarations.
* Using the key `$implicit` in the context object will set its value as default.
*/
@Input() public ngTemplateOutletContext: C | null = null;
@Input() public ngTemplateOutletContext: C | null | undefined = null;

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

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

constructor(private _viewContainerRef: ViewContainerRef) {}

Expand Down
29 changes: 29 additions & 0 deletions 29 packages/common/test/directives/ng_template_outlet_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ describe('NgTemplateOutlet', () => {
detectChangesAndExpectText('');
}));

it('should do nothing if templateRef is `undefined`', waitForAsync(() => {
const template = `<ng-container [ngTemplateOutlet]="undefined"></ng-container>`;
fixture = createTestComponent(template);
detectChangesAndExpectText('');
}));

it('should insert content specified by TemplateRef', waitForAsync(() => {
const template =
`<ng-template #tpl>foo</ng-template>` +
Expand All @@ -93,6 +99,21 @@ describe('NgTemplateOutlet', () => {
detectChangesAndExpectText('');
}));

it('should clear content if TemplateRef becomes `undefined`', waitForAsync(() => {
const template =
`<tpl-refs #refs="tplRefs"><ng-template>foo</ng-template></tpl-refs>` +
`<ng-container [ngTemplateOutlet]="currentTplRef"></ng-container>`;
fixture = createTestComponent(template);
fixture.detectChanges();
const refs = fixture.debugElement.children[0].references!['refs'];

setTplRef(refs.tplRefs.first);
detectChangesAndExpectText('foo');

setTplRef(undefined);
detectChangesAndExpectText('');
}));

it('should swap content if TemplateRef changes', waitForAsync(() => {
const template =
`<tpl-refs #refs="tplRefs"><ng-template>foo</ng-template><ng-template>bar</ng-template></tpl-refs>` +
Expand All @@ -117,6 +138,14 @@ describe('NgTemplateOutlet', () => {
detectChangesAndExpectText('foo');
}));

it('should display template if context is `undefined`', waitForAsync(() => {
const template =
`<ng-template #tpl>foo</ng-template>` +
`<ng-container *ngTemplateOutlet="tpl; context: undefined"></ng-container>`;
fixture = createTestComponent(template);
detectChangesAndExpectText('foo');
}));

it('should reflect initial context and changes', waitForAsync(() => {
const template =
`<ng-template let-foo="foo" #tpl>{{foo}}</ng-template>` +
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.