Skip to content

Commit 24373e1

Browse files
committed
docs: migrate to signals and takeUntilDestroyed
- Replace lifecycle hooks with constructor initialization - Convert properties to signals (items, section, _categoryListSummary) - Use takeUntilDestroyed() for automatic cleanup - Replace async/await with switchMap to prevent race conditions - Remove manual subscription management Benefits: Better performance, automatic cleanup, safer async handling
1 parent 2b85d59 commit 24373e1

File tree

2 files changed

+48
-40
lines changed

2 files changed

+48
-40
lines changed

docs/src/app/pages/component-category-list/component-category-list.html

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
1-
<div class="docs-component-category-list-summary docs-markdown"
2-
id="category-summary"
3-
focusOnNavigation>
4-
<div [innerHTML]="_categoryListSummary"></div>
1+
<div
2+
class="docs-component-category-list-summary docs-markdown"
3+
id="category-summary"
4+
focusOnNavigation
5+
>
6+
<div [innerHTML]="_categoryListSummary()"></div>
57
</div>
6-
@if (items.length > 0) {
8+
@if (items().length > 0) {
79
<div class="docs-component-category-list">
8-
@for (component of items; track component) {
9-
<a class="docs-component-category-list-item"
10-
[routerLink]="'/' + section + '/' + component.id">
10+
@for (component of items(); track component.id) {
11+
<a
12+
class="docs-component-category-list-item"
13+
[routerLink]="'/' + section() + '/' + component.id"
14+
>
1115
<div class="docs-component-category-list-card" matRipple>
12-
@if (section === 'components') {
13-
<img class="docs-component-category-list-card-image-wrapper"
14-
[src]="'../../../assets/screenshots/' + component.id + '.scene.png'"
15-
loading="lazy"
16-
alt=""
17-
role="presentation"
18-
aria-hidden="true">
16+
@if (section() === 'components') {
17+
<img
18+
class="docs-component-category-list-card-image-wrapper"
19+
[src]="'../../../assets/screenshots/' + component.id + '.scene.png'"
20+
loading="lazy"
21+
alt=""
22+
role="presentation"
23+
aria-hidden="true"
24+
/>
1925
}
2026
<div class="docs-component-category-list-card-title">{{component.name}}</div>
2127
<div class="docs-component-category-list-card-summary">{{component.summary}}</div>

docs/src/app/pages/component-category-list/component-category-list.ts

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Component, OnDestroy, OnInit, inject} from '@angular/core';
9+
import {Component, inject, signal} from '@angular/core';
1010
import {ActivatedRoute, RouterLink} from '@angular/router';
1111
import {MatRipple} from '@angular/material/core';
12-
import {combineLatest, Subscription} from 'rxjs';
12+
import {combineLatest} from 'rxjs';
1313

1414
import {
1515
DocItem,
@@ -19,40 +19,42 @@ import {
1919
import {NavigationFocus} from '../../shared/navigation-focus/navigation-focus';
2020

2121
import {ComponentPageTitle} from '../page-title/page-title';
22+
import {map, switchMap, takeUntil} from 'rxjs/operators';
23+
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
2224

2325
@Component({
2426
selector: 'app-component-category-list',
2527
templateUrl: './component-category-list.html',
2628
styleUrls: ['./component-category-list.scss'],
2729
imports: [NavigationFocus, RouterLink, MatRipple],
2830
})
29-
export class ComponentCategoryList implements OnInit, OnDestroy {
31+
export class ComponentCategoryList {
3032
private readonly _docItems = inject(DocumentationItems);
3133
private readonly _componentPageTitle = inject(ComponentPageTitle);
3234
private readonly _route = inject(ActivatedRoute);
3335

34-
items: DocItem[] = [];
35-
section = '';
36-
routeParamSubscription: Subscription = new Subscription();
37-
_categoryListSummary: string | undefined;
38-
39-
ngOnInit() {
40-
this.routeParamSubscription = combineLatest(
41-
this._route.pathFromRoot.map(route => route.params),
42-
Object.assign,
43-
).subscribe(async params => {
44-
const sectionName = params['section'];
45-
const section = SECTIONS[sectionName];
46-
this._componentPageTitle.title = section.name;
47-
this._categoryListSummary = section.summary;
48-
this.section = sectionName;
49-
this.items = await this._docItems.getItems(sectionName);
50-
});
51-
}
36+
readonly items = signal<DocItem[]>([]);
37+
readonly section = signal<string>('');
38+
readonly _categoryListSummary = signal<string | undefined>(undefined);
39+
40+
constructor() {
41+
combineLatest(this._route.pathFromRoot.map(route => route.params))
42+
.pipe(
43+
map(paramsArray => Object.assign({}, ...paramsArray)),
44+
switchMap(params => {
45+
const sectionName = params['section'];
46+
const section = SECTIONS[sectionName];
47+
48+
this._componentPageTitle.title = section.name;
49+
this._categoryListSummary.set(section.summary);
50+
this.section.set(sectionName);
5251

53-
ngOnDestroy() {
54-
if (this.routeParamSubscription) {
55-
this.routeParamSubscription.unsubscribe();
56-
}
52+
return this._docItems.getItems(sectionName);
53+
}),
54+
takeUntilDestroyed(),
55+
)
56+
.subscribe(items => {
57+
this.items.set(items);
58+
});
5759
}
5860
}

0 commit comments

Comments
 (0)