0%

What's new in Angular 18

Over the past three releases, Angular team introduced a lot of new features and improvements, Angular 18 focused on polishing the previous work and graduating many of the new APIs from experimental to stable. another exciting feature is zoneless change detection - still in experimental phase. Here is the content table:

  1. Zoneless Change Detection
  2. angular.dev is the new home for angular developers
  3. Stable features: Material 3, deferrable views, built-in control flows
  4. SSR improvements: i18n hydration support, better debugging, hydration support in Angular Material.
  5. Native await for zoneless apps.
  6. Fallback content for ng-content.

Zoneless Change Detection

1
2
3
4
5
bootstrapApplication(App, {
providers: [
provideExperimentalZonelessChangeDetection()
]
});

Then remove zone.js from file angular.json in your project.

Testing

HttpClientTestingModule is deprecated, use `` instead.

Before:

1
2
3
4
5
6
7
8
9
import { HttpClientTestingModule } from '@angular/common/http/testing';

//...

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HttpClientTestingModule], // <-- Here
}).compileComponents();
});

Now

1
2
3
4
5
6
7
8
9
import { provideHttpClientTesting } from '@angular/common/http/testing';

beforeEach(async () => {
await TestBed.configureTestingModule({
providers: [
provideHttpClientTesting(),
]
}).compileComponents();
});

Native await for zoneless apps

因为Angular一直使用zone.js实现更新检测,但是async/await语法zone.js一直无法做monkey patch,导致在zone.js中使用promise来模拟,现在如果你的app不是用zone.js,那么Angular就不会再使用promise来模拟async/await,而是直接使用原生的async/await。

Specifying a fallback content for ng-content

ng-content现在可以指定一个fallback content,当没有传递内容时,会显示这个fallback content。

1
2
3
4
5
6
7
8
9
@Component({
selector: 'app-profile',
template: `
<ng-content select=".greeting">Hello </ng-content>

<ng-content>Unknown user</ng-content>
`,
})
export class Profile {}

调用代码:

1
2
3
<app-profile>
<span class="greeting">Good morning </span>
</app-profile>

which will result in:

1
2
<span class="greeting">Good morning </span>
Unknown user
  1. We specified Good morning for the first ng-content, so the fallback Hello won’t be displayed.
  2. We didn’t specify any content for the second ng-content, so the fallback Unknown user will be displayed.

Unified control state change events

1
2
3
4
const nameControl = new FormControl<string|null>('name', Validators.required);
nameControl.events.subscribe(event => {
// process the individual events
});

Router redirect as function

The redirectTo property in the route configuration can now be a function that returns a URL string or an array of URL segments.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const routes: Routes = [
{ path: "first-component", component: FirstComponent },
{
path: "old-user-page",
redirectTo: ({ queryParams }) => {
const errorHandler = inject(ErrorHandler);
const userIdParam = queryParams['userId'];
if (userIdParam !== undefined) {
return `/user/${userIdParam}`;
} else {
errorHandler.handleError(new Error('Attempted navigation to user page without user ID.'));
return `/not-found`;
}
},
},
{ path: "user/:userId", component: OtherComponent },
];

Support typescript 5.4

References:

  1. https://blog.angular.dev/angular-v18-is-now-available-e79d5ac0affe