If/else and even else if!
Traditionally we’d do
<div *ngIf="usingLatest; else outdated">
You’re using the latest version.
</div>
<ng-template #outdated>
You are using an outdated version
</ng-template>
Now we can do
@if (usingLatest) {
Thank you for using the latest version
} @else {
You are using an outdated version
}
This construction also allows us to write an if/else if/else construction which formerly wasn’t possible.
Iteration
To loop over a list of elements we’d perform
<div *ngFor="let angularRelease of angularReleases">
Release: {{ angularRelease.versionNumber }} - Date: {{ angularRelease.date }} <br>
</div>
With optionally a trackBy function. In the new approach, track is mandatory. The new for statement uses a new diffing algorithm which is quite a bit faster according to community framework benchmarks.
It’s also quite easy to add an empty placeholder.
@for (angularRelease of angularReleases; track angularRelease.versionNumber) {
Release: {{ angularRelease.versionNumber }} - Date: {{ angularRelease.date }} <br>
} @empty {
Empty list of releases
}
Switches
Switches have also become quite a lot more convenient, from:
<div [ngSwitch]="roll">
<app-one *ngSwitchCase="1"/>
<app-two *ngSwitchCase="2"/>
<app-three *ngSwitchDefault/>
</div>
To
@switch (roll) {
@case (1) { <app-one/> }
@case (2) { <app-two/> }
@default { <app-three/> }
}
Deferrable views
This is the planned roads forwards for lazy loading. It utilizes the new block mechanism for standalone components to make our applications faster, by as the name implies easily facilitating declarative, deferred loading. One of the nice things about this, is that this all also happens at compile-time, all the complexity is abstracted away.
Let’s use this example:
@defer (on hover) {
<app-heavy/>
} @loading {
Loading…
} @error {
Loading failed
} @placeholder (minimum 2000ms) {
<div>Placeholder that will be shown for 2000ms minimally (to prevent flickering in case the deferred component loads quickly)</div>
}
In this example, we’re deferring the loading of a heavy component, until the block’s been hovered over. In the interim we’ll be showcasing the placeholder (and in this case, minimally for 2 seconds). After which we’ll see either the loading in case it takes long/the result/loading failed in case of an error.
Only @defer is required, @loading | @error | @placeholder are all optional.
There possible triggers are:
- on idle => there default, triggers loading once the browser has reached an idle state
- on viewport => when the specified content enters the viewport
- on hover => when the user hovers over the trigger area
- on interact => when the user interacts with the specified element
- on immediate => triggered once the client has finished rendering
- on timer => delays the loading with a timer
Another nice thing is that deferrable views also allow us the option to prefetch dependencies before rendering them. This can be done by adding a prefetch to the defer block (the same triggers as above are supported).
@defer (on viewport; prefetch on idle) {...}