<!-- LEt talk about ng-template more
ng-template defined in component.html has access to all variable from component.ts
say courses, apples= 10 etc. defined in component.ts..
and each ng-template can also define its own set of input variables!
Actually, each template has associated a context object containing
all the template-specific input variables. ===-->
<ng-template #hello let-lessonsCounter="estimate">
<div> Approximately {{lessonsCounter}} lessons ...</div>
</ng-template>
<ng-container *ngTemplateOutlet="hello;context:foo"> </ng-container>
<!--inside Component.ts -->
totalEstimate = 10;
foo = {estimate: this.totalEstimate};
or
foo = { estimate: 10 }
<!--
The input variable is called lessonsCounter,and
it's defined via a ng-template property using the prefix let-
The variable lessonsCounter is visible inside the ng-template body, but not outside
the content of lessonsCounter variable is determined by the expression that its assigned to the
property let-lessonsCounter = "estimate"
Remember, foo is object passed to ng-container along with hello template reference like this
" *ngTemplateOutlet="hello; context: foo " so, foo = { estimate: 10 }
The object foo should contain a property estimate which is expressed in ng-template as
let-lessonsCounter="estimate" so that is used within template
let-lessonsCounter="estimate" and foo = { estimate: 10} or foo = {estimate: this.number}
if a button runs a function that change number, estimate change, foo changes,
ng-container refer to hello ng-template and lessonsCounter change and value on screen change
<!--=== This will throw an Syntax Error, Multiple Structural Directives ngif and ngfor on one Element ===-->
<div *ngIf="lessons" class="lesson" *ngFor="let lesson of lessons">
<div class="lesson-detail">{{lesson | json}}</div>
</div>
<!--=== Right but older way without ng-template and we have create an extra div for ngIf ===-->
<div *ngIf="lessons">
<div class="lesson" *ngFor="let lesson of lessons">
<div class="lesson-detail">{{lesson | json}}</div>
</div>
</div>
<!--=== Right and better way and it also avoids having to create that extra div,
we can instead use ng-container directive: ===-->
<ng-container *ngIf="lessons">
<div class="lesson" *ngFor="let lesson of lessons">
<div class="lesson-detail">{{lesson | json}}</div>
</div>
</ng-container>
<!-- === Ng-container directive provides us with an element
that we can attach a structural directive to a section of the page,
without having to create an extra element just for that.
There is another major use case for the ng-container directive:
it can also provide a placeholder for injecting a template
dynamically into the page. ===-->
<!--=== Dynamic Template Creation with the ngTemplateOutlet directive ===-->
<!--=== Being able to create template references and point them to other
directives such as ngIf is just the beginning. ===-->
<!--=== We can also take the template itself and instantiate it anywhere
on the page, using the ngTemplateOutlet directive: ===-->
<ng-container *ngTemplateOutlet="loading"></ng-container>
<!--=== Here loading is reference to ng-template with #loading ===-->
<!-- ng-template Renders Nothing unless called -->
<ng-template>
<button class="tab-button"
(click)="login()">{{loginText}}</button>
<button class="tab-button"
(click)="signUp()">{{signUpText}}</button>
</ng-template>
<!-- This Renders because ng-template called -->
<div class="lessons-list" *ngIf="lessons else loading">
...
</div>
<ng-template #loading>
<div>Loading...</div>
</ng-template>