As you can see in the source code, using *ngTemplateOutlet
and [ngTemplateOutlet]
does not differ since you are using the very same class.
Looking at the class you can see this property:
@Input() public ngTemplateOutletContext: C | null = null;
This translates in the following snippets being almost equivalent:
<ng-container *ngTemplateOutlet="content; context: myContextObj">
</ng-container>
<ng-container [ngTemplateOutlet]="content"
[ngTemplateOutletContext]="myContextObj">
</ng-container>
In fact, using the *
shorthand you can specify the inputs if the Directive
follwed by a semicolon.
This is true for every structural directive: they can be used referring to their selector
or can be used with the structural directive *
shorthand.
What happens under the hood to make the former snippets different?
If you take a look at the docs I linked you will see that while using the *
shorthand, Angular will wrap your element in a ng-template
and will apply the directive with the selector to it:
From the docs, these two templates are equivalent:
<div class="name" *ngIf="hero">{{hero.name}}</div>
<ng-template [ngIf]="hero">
<div class="name">{{hero.name}}</div>
</ng-template>
You see that with these powerful tools complexity can escalate quickly, so Angular does not allow 2 structural directives on the same element because it would be impossible to priorly know which directive should have the priority.
This is maybe the only difference between the two approaches that can affect developer experience: if you want to use ngTemplateOutlet
and another structural directive, you have 2 possibilities:
- Wrap the element in a
ng-container
and use the structural directive in 2 different elements
- Use only one
*
shorthand
// Using 2 "*" shorthand in the same element: the code won't compile
<ng-container *ngTemplateOutlet="content" *ngIf="true">
</ng-container>
// Approach 1, the code will compile
<ng-container *ngIf="true">
<ng-container *ngTemplateOutlet="content">
</ng-container>
</ng-container>
// Approach 2, the code will compile
<ng-container [ngTemplateOutlet]="content" *ngIf="true">
</ng-container>