Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions 01-setup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,28 +204,7 @@ canvas based on the container dimensions, so an explicit size is required.

---

## 8. Zoneless change detection

Angular's default change detection relies on Zone.js to intercept browser APIs.
Since yFiles fires its own events outside Angular's zone, it is cleaner to
opt in to **zoneless** change detection:

```ts
// src/app/app.config.ts
import { provideZonelessChangeDetection } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [provideBrowserGlobalErrorListeners(), provideZonelessChangeDetection()],
}
```

With zoneless change detection, Angular only re-evaluates templates when a
signal value changes. This avoids spurious change-detection cycles triggered
by yFiles' internal DOM updates.

---

## 9. Run it
## 8. Run it

```bash
npm start
Expand All @@ -247,7 +226,6 @@ Open `http://localhost:4200`. You should see a blank white canvas. Try panning
| `@ViewChild` | Gives access to a template element reference by name. |
| `ngAfterViewInit()` | Lifecycle hook that fires after the template is rendered. Use for DOM access. |
| `GraphViewerInputMode` | Read-only interaction: pan, zoom, select. No graph editing. |
| `provideZonelessChangeDetection()` | Disables Zone.js; Angular only re-evaluates signals. Avoids spurious cycles from yFiles events. |

---

Expand Down
13 changes: 2 additions & 11 deletions 01-setup/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import {
type ApplicationConfig,
provideBrowserGlobalErrorListeners,
provideZonelessChangeDetection,
} from '@angular/core'
import { type ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
// Angular 21 uses zoneless change detection by default.
// This is more efficient and works well with yFiles' imperative API.
provideBrowserGlobalErrorListeners(),
provideZonelessChangeDetection(),
],
providers: [provideBrowserGlobalErrorListeners()],
}
13 changes: 2 additions & 11 deletions 02-first-graph/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import {
type ApplicationConfig,
provideBrowserGlobalErrorListeners,
provideZonelessChangeDetection,
} from '@angular/core'
import { type ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
// Angular 21 uses zoneless change detection by default.
// This is more efficient and works well with yFiles' imperative API.
provideBrowserGlobalErrorListeners(),
provideZonelessChangeDetection(),
],
providers: [provideBrowserGlobalErrorListeners()],
}
21 changes: 20 additions & 1 deletion 03-graph-builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ cause new elements to be created; missing IDs cause removal.
## 5. Angular signals — the reactive state layer

This chapter introduces Angular's **signals API** as the reactive bridge
between application data and the graph.
between application data and the graph. See the Angular [Signals](https://angular.dev/guide/signals) documentation for in-depth explanations.

### `signal<T>()` — mutable reactive state

Expand Down Expand Up @@ -209,6 +209,25 @@ constructor(
) {}
```

### Signals and zoneless change detection

Angular 21 uses **zoneless** change detection by default. This means Angular no
longer relies on Zone.js — the library that traditionally monkey-patched browser
async APIs to trigger change detection after every Promise, `setTimeout`, or event.

Signals are what make this possible. When a template reads a signal, Angular
registers an exact dependency. When that signal changes, only the affected views
are re-evaluated — Angular always knows precisely what changed.

For a yFiles app this matters: yFiles' own render loop and internal event handlers
would otherwise trigger unnecessary change-detection passes under Zone.js. With
signals + zoneless, Angular and yFiles stay out of each other's way entirely.

`app.config.ts` only needs `provideBrowserGlobalErrorListeners()` — no explicit
change-detection configuration is required.

See the Angular [Zoneless](https://angular.dev/guide/zoneless) documentation for further information.

---

## 6. `GraphViewComponent` — full implementation
Expand Down
13 changes: 2 additions & 11 deletions 03-graph-builder/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import {
type ApplicationConfig,
provideBrowserGlobalErrorListeners,
provideZonelessChangeDetection,
} from '@angular/core'
import { type ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
// Angular 21 uses zoneless change detection by default.
// This is more efficient and works well with yFiles' imperative API.
provideBrowserGlobalErrorListeners(),
provideZonelessChangeDetection(),
],
providers: [provideBrowserGlobalErrorListeners()],
}
13 changes: 2 additions & 11 deletions 04-styles-and-interaction/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import {
type ApplicationConfig,
provideBrowserGlobalErrorListeners,
provideZonelessChangeDetection,
} from '@angular/core'
import { type ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
// Angular 21 uses zoneless change detection by default.
// This is more efficient and works well with yFiles' imperative API.
provideBrowserGlobalErrorListeners(),
provideZonelessChangeDetection(),
],
providers: [provideBrowserGlobalErrorListeners()],
}
13 changes: 2 additions & 11 deletions 05-layout-worker/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import {
type ApplicationConfig,
provideBrowserGlobalErrorListeners,
provideZonelessChangeDetection,
} from '@angular/core'
import { type ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
// Angular 21 uses zoneless change detection by default.
// This is more efficient and works well with yFiles' imperative API.
provideBrowserGlobalErrorListeners(),
provideZonelessChangeDetection(),
],
providers: [provideBrowserGlobalErrorListeners()],
}