February 16, 2024 08:10 by
Peter
As part of its new movement, Angular 17 provides Signals and Standalone Components. You can anticipate an enhanced Angular Renaissance with Angular 17. It features enhanced support for Server-Side Rendering (SSR), a new control flow syntax, and greater support for lazy loading of page components. Furthermore, the CLI now uses ESBuild, which greatly improves the build procedure.
Integrated Control Flow Automated Transfer
The @angular/core package contains a schematic that you can use to automatically convert your code to the new control flow syntax.
ng g @angular/core:control-flow
Technical Updates in Angular
New looping syntax
- If-then-else
- Switch
- Block directives
- Deferred rendering
- SSR and SSG
- New build system
- Improved debugging for dependency injection
New Looping Syntax
You can see a live example of the new looping capability in the Angular playground. In this example, we loop over an array of to-do items.
@for (todo of todos; track $index) {
...
}
That’s pretty succinct. We expose the todo variable for each element of todos, and we “track” the built-in $index field. The $index variable will show the automatically generated row number for the element (there are other implicit variables like $first, $odd, and $count). You can also use a field on the elements you want to track.
@for (todo of todos; track todo.id) {...}
In this new syntax, the track variable is required, by design. In previous incarnations, the tracking variable was optional, which led to performance degradation. The tracking key on a loop enables the rendering engine to optimize the list display and know what has changed.
If-then-else
@if (todo.done) {
<s>{{ todo.text }}</s>
} @else {
<span>{{ todo.text }}</span>
}
Being able to provide the content for @else directly is a major simplification compared to the else clause of the legacy *ngIf alternative. The current control flow also makes it trivial to have @else if, which historically has been impossible.
Switch
Angular’s new switch syntax applies typical JavaScript syntax to templates.
@switch (condition) {
@case (caseA) {
<span>Case A.</span>
}
@case (caseB) {
<span>Case B.</span>
}
@default {
<span>Default case.</span>
}
}
The new control flow enables significantly better type-narrowing in the individual branches in @switch which is not possible in *ngSwitch.
Deferred Rendering
Angular now supports deferred rendering via the block syntax. This gives you a simple and powerful mechanism for defining ways to tell the browser what to display along with instructions for doing it in a non-linear way. The Angular 17 tutorial has some good examples of using @defer.
Here's an example of the simplest @defer.
@defer {
<span>My deferred content</span>
}
This tells the browser to render the rest of the page first, and then the deferred content. It's a very simple syntax for the times when you want to avoid front-loading everything.
You can also provide @placeholder and @loading blocks.
@defer {
<span>My deferred content</span>
}
@placeholder {
<span>Placeholder content</span>
}
@loading {
<span>Loading deferred content...</span>
}
Placeholder and loading both provide a static layout for the coming content, @placeholder first, then @loading.
Several different strategies are supported by @defer out of the box, like viewport (when the user scrolls it into view), idle (browser is idle), interaction (user interacts with the element), and hover (pointer hovers on the element). Here's an example using hover.
@defer (on hover) {
<span>My hover content</span>
}
There’s even a @defer(when <expression>) that takes a promise, so you can really defer on any conceivable situation. All in all, the new @defer mechanism is impressive. Deferred rendering is usually persnickety and really interferes with the flow of a developer's thoughts and the resulting code. This latest version of Angular makes it easy.
Note that @defer is still a developer preview in Angular 17, but is considered production-ready.
New Build System
Angular has joined the Vite movement, and Angular 17 uses Vite with Esbuild as its build engine. This was a required change for underpinning the new SSR system. For developers, the main impact is that it's faster, including for serving and updating in dev mode.
Block Directives
@for, @if, and @switch are new “block” directives. They allow us to inject chunks of markup into the template using JavaScript syntax. These new directives replace previous approaches like *ngIf. You can still use *ngIf and other older syntax, and an automated command in the CLI lets you change over to the block syntax.
ng generate @angular/core:control-flow