• When we talk about the Angular microsyntax, we are actually talking about structural directives.
  • We could actually program without using the microsyntax at all.
  • It is basically just syntactic sugar to write less code in your Angular template.

How the microsyntax gets transformed

Without the microsyntax we would write the following.
(The localItems template variable doesn't make sense here. It's just here to illustrate you the repeated pattern for the 'as' translation.)

<ng-template [ngIf]="items$ | async" let-items="ngIf">
    <ng-template ngFor [ngForOf]="items" [ngForTrackBy]="trackById" let-localItems="ngForOf" let-item let-i="index" let-c="count">
      <li>{{item}} {{i}} / {{c}}</li>

With the microsyntax we write way less code to achieve the the same:

<ul *ngIf="items$ | async as items">
  <li *ngFor="let item of items as localItems; trackBy: trackById; index as i">{{item}}</li>
  1. By applying the * (star) prefix we turn every attribute directive into a structural directive.
  2. The microsyntax then automatically transforms / wraps that element with an <ng-template />.

Why should I know that?

Because it will shift the target element (ViewContainerRef, TemplateRef, ElementRef) we are decorating in our template.
Instead of an <ul /> or <li /> element, we now get an <ng-template /> injected in our directive class constructor.

How to bind ng-template input variables

To create template input variables (let-items, etc.) we have to know and reference the corresponding context variables (aka export values).

// This is a simplified version of the NgIfContext
interface NgIfContext<T> {
  $implicit: T;  // let-item
  ngIf: T;       // let-items (this has to match the directive selector 'ngIf' to support the 'as' variable binding)

// This is a simplified version of the NgForOfContext
interface NgForOfContext<T, U> {
  $implicit: T;     // let-item
  ngForOf: U;       // let-localItems (this has to match the directive selector 'ngForOf' to support the 'as' variable binding)
  index: number;    // let-i="index"
  count: number;    // let-c="count"

We apply the context / export values through the ViewContainerRef.

this.viewContainterRef.createEmbeddedView(this.templateRef, this.context)

The microsyntax is probably one of the hardest thing to understand in Angular but critical to know because we use it all the time.