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' ;
1010import { ActivatedRoute , RouterLink } from '@angular/router' ;
1111import { MatRipple } from '@angular/material/core' ;
12- import { combineLatest , Subscription } from 'rxjs' ;
12+ import { combineLatest } from 'rxjs' ;
1313
1414import {
1515 DocItem ,
@@ -19,40 +19,63 @@ import {
1919import { NavigationFocus } from '../../shared/navigation-focus/navigation-focus' ;
2020
2121import { ComponentPageTitle } from '../page-title/page-title' ;
22+ import { map , switchMap } 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+ // Combine all route parameters from root to current route into a single observable
42+ // pathFromRoot gives us the entire route hierarchy (e.g., /docs/:category/:section)
43+ combineLatest ( this . _route . pathFromRoot . map ( route => route . params ) )
44+ . pipe (
45+ // Merge all parameter objects into one, with child route params overriding parent params
46+ // Example: [{category: 'components'}, {section: 'button'}] becomes {category: 'components', section: 'button'}
47+ map ( paramsArray => paramsArray . reduce ( ( acc , curr ) => ( { ...acc , ...curr } ) , { } ) ) ,
48+
49+ // Switch to a new observable when params change, canceling any pending requests
50+ // This prevents race conditions if the user navigates quickly between sections
51+ switchMap ( params => {
52+ // Extract the section name from route parameters
53+ const sectionName = params [ 'section' ] ;
54+
55+ // Look up section metadata from the SECTIONS configuration
56+ const section = SECTIONS [ sectionName ] ;
57+
58+ // Update page title in browser tab/window
59+ this . _componentPageTitle . title = section . name ;
60+
61+ // Update component state with section summary (displayed in UI)
62+ this . _categoryListSummary . set ( section . summary ) ;
63+
64+ // Store current section name
65+ this . section . set ( sectionName ) ;
66+
67+ // Fetch documentation items for this section from the service
68+ // switchMap will cancel this request if route params change before completion
69+ return this . _docItems . getItems ( sectionName ) ;
70+ } ) ,
5271
53- ngOnDestroy ( ) {
54- if ( this . routeParamSubscription ) {
55- this . routeParamSubscription . unsubscribe ( ) ;
56- }
72+ // Automatically unsubscribe when component is destroyed (no manual cleanup needed)
73+ takeUntilDestroyed ( ) ,
74+ )
75+ . subscribe ( items => {
76+ // Update the items signal with fetched documentation items
77+ // This triggers change detection and updates the template
78+ this . items . set ( items ) ;
79+ } ) ;
5780 }
5881}
0 commit comments