Skip to content
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 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 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 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