@anglr/select 16.0.3 → 16.0.4-beta.20260511085948

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.claude/skills/angular-developer/SKILL.md +130 -0
  2. package/.claude/skills/angular-developer/references/angular-animations.md +160 -0
  3. package/.claude/skills/angular-developer/references/angular-aria.md +410 -0
  4. package/.claude/skills/angular-developer/references/cli.md +86 -0
  5. package/.claude/skills/angular-developer/references/component-harnesses.md +59 -0
  6. package/.claude/skills/angular-developer/references/component-styling.md +91 -0
  7. package/.claude/skills/angular-developer/references/components.md +117 -0
  8. package/.claude/skills/angular-developer/references/creating-services.md +97 -0
  9. package/.claude/skills/angular-developer/references/data-resolvers.md +69 -0
  10. package/.claude/skills/angular-developer/references/define-routes.md +67 -0
  11. package/.claude/skills/angular-developer/references/defining-providers.md +72 -0
  12. package/.claude/skills/angular-developer/references/di-fundamentals.md +120 -0
  13. package/.claude/skills/angular-developer/references/e2e-testing.md +66 -0
  14. package/.claude/skills/angular-developer/references/effects.md +83 -0
  15. package/.claude/skills/angular-developer/references/hierarchical-injectors.md +43 -0
  16. package/.claude/skills/angular-developer/references/host-elements.md +80 -0
  17. package/.claude/skills/angular-developer/references/injection-context.md +63 -0
  18. package/.claude/skills/angular-developer/references/inputs.md +101 -0
  19. package/.claude/skills/angular-developer/references/linked-signal.md +59 -0
  20. package/.claude/skills/angular-developer/references/loading-strategies.md +61 -0
  21. package/.claude/skills/angular-developer/references/mcp.md +106 -0
  22. package/.claude/skills/angular-developer/references/migrations.md +30 -0
  23. package/.claude/skills/angular-developer/references/navigate-to-routes.md +69 -0
  24. package/.claude/skills/angular-developer/references/outputs.md +86 -0
  25. package/.claude/skills/angular-developer/references/reactive-forms.md +122 -0
  26. package/.claude/skills/angular-developer/references/rendering-strategies.md +44 -0
  27. package/.claude/skills/angular-developer/references/resource.md +77 -0
  28. package/.claude/skills/angular-developer/references/route-animations.md +56 -0
  29. package/.claude/skills/angular-developer/references/route-guards.md +52 -0
  30. package/.claude/skills/angular-developer/references/router-lifecycle.md +45 -0
  31. package/.claude/skills/angular-developer/references/router-testing.md +87 -0
  32. package/.claude/skills/angular-developer/references/show-routes-with-outlets.md +68 -0
  33. package/.claude/skills/angular-developer/references/signal-forms.md +897 -0
  34. package/.claude/skills/angular-developer/references/signals-overview.md +94 -0
  35. package/.claude/skills/angular-developer/references/tailwind-css.md +69 -0
  36. package/.claude/skills/angular-developer/references/template-driven-forms.md +114 -0
  37. package/.claude/skills/angular-developer/references/testing-fundamentals.md +66 -0
  38. package/.github/instructions/typescript/code-conventions.md +8 -0
  39. package/.github/instructions/typescript/comments.md +41 -0
  40. package/.github/instructions/typescript/formatting.md +42 -0
  41. package/.github/instructions/typescript/naming-conventions.md +7 -0
  42. package/.github/instructions/typescript.instructions.md +26 -0
  43. package/package.json +1 -1
  44. package/readme.md +1288 -99
  45. package/version.bak +1 -1
  46. package/.github/copilot-instructions.md +0 -1
@@ -0,0 +1,86 @@
1
+ # Angular CLI Guide for Agents
2
+
3
+ The Angular CLI (`ng`) is the primary tool for managing an Angular workspace. Always prefer CLI commands over manual file creation or generic `npm` commands when modifying project structure or adding Angular-specific dependencies.
4
+
5
+ ## 1. Managing Dependencies
6
+
7
+ **ALWAYS use `ng add` for Angular libraries** instead of `npm install`. `ng add` installs the package AND runs initialization schematics (e.g., configuring `angular.json`, updating root providers).
8
+
9
+ ```bash
10
+ ng add @angular/material
11
+ ng add tailwindcss
12
+ ng add @angular/fire
13
+ ```
14
+
15
+ To update the application and its dependencies (which automatically runs code migrations):
16
+
17
+ ```bash
18
+ ng update @angular/core@<latest or specific version> @angular/cli<latest or specific version>
19
+ ```
20
+
21
+ ## 2. Generating Code (`ng generate` or `ng g`)
22
+
23
+ Always use the CLI to generate code to ensure it adheres to Angular standards and updates necessary configuration files automatically.
24
+
25
+ | Target | Command | Notes |
26
+ | :----------- | :-------------------- | :--------------------------------------------------------------------------------------------- |
27
+ | Component | `ng g c path/to/name` | Generates a component. Use `--inline-style` (`-s`) or `--inline-template` (`-t`) if requested. |
28
+ | Service | `ng g s path/to/name` | Generates an `@Injectable({providedIn: 'root'})` service. |
29
+ | Directive | `ng g d path/to/name` | Generates a directive. |
30
+ | Pipe | `ng g p path/to/name` | Generates a pipe. |
31
+ | Guard | `ng g g path/to/name` | Generates a functional route guard. |
32
+ | Environments | `ng g environments` | Scaffolds `src/environments/` and updates `angular.json` with file replacements. |
33
+
34
+ _Note: There is no command to generate a single route definition. Generate a component, then manually add it to the `Routes` array in `app.routes.ts`._
35
+
36
+ ## 3. Development Server & Proxying
37
+
38
+ Start the local development server with hot-module replacement (HMR):
39
+
40
+ ```bash
41
+ ng serve
42
+ ```
43
+
44
+ ### Backend API Proxying
45
+
46
+ To proxy API requests during development (e.g., rerouting `/api` to a local Node server):
47
+
48
+ 1. Create `src/proxy.conf.json`:
49
+ ```json
50
+ {
51
+ "/api/**": {"target": "http://localhost:3000", "secure": false}
52
+ }
53
+ ```
54
+ 2. Update `angular.json` under the `serve` target:
55
+ ```json
56
+ "serve": {
57
+ "builder": "@angular/build:dev-server",
58
+ "options": { "proxyConfig": "src/proxy.conf.json" }
59
+ }
60
+ ```
61
+
62
+ ## 4. Building the Application
63
+
64
+ Compile the application into an output directory (default: `dist/<project-name>/browser`). Modern Angular uses the `@angular/build:application` builder (esbuild-based).
65
+
66
+ ```bash
67
+ ng build
68
+ ```
69
+
70
+ - `ng build` defaults to the production configuration, which enables Ahead-of-Time (AOT) compilation, minification, and tree-shaking.
71
+ - Target specific configurations defined in `angular.json` using `--configuration`: `ng build --configuration=staging`.
72
+
73
+ ## 5. Testing
74
+
75
+ - **Unit Tests**: Run `ng test` to execute unit tests via the configured test runner (e.g., Karma or Vitest).
76
+ - **End-to-End (E2E)**: Run `ng e2e`. If no E2E framework is configured, the CLI will prompt to install one (Cypress, Playwright, Puppeteer, etc.).
77
+
78
+ ## 6. Deployment
79
+
80
+ To deploy an application, you must first add a deployment builder, then run the deploy command:
81
+
82
+ ```bash
83
+ # Example for Firebase
84
+ ng add @angular/fire
85
+ ng deploy
86
+ ```
@@ -0,0 +1,59 @@
1
+ # Testing with Component Harnesses
2
+
3
+ Component harnesses are the standard, preferred way to interact with components in tests. They provide a robust, user-centric API that makes tests less brittle and easier to read by insulating them from changes to a component's internal DOM structure.
4
+
5
+ ## Why Use Harnesses?
6
+
7
+ - **Robustness:** Tests don't break when you refactor a component's internal HTML or CSS classes.
8
+ - **Readability:** Tests describe interactions from a user's perspective (e.g., `button.click()`, `slider.getValue()`) instead of through DOM queries (`fixture.nativeElement.querySelector(...)`).
9
+ - **Reusability:** The same harness can be used in both unit tests and E2E tests.
10
+
11
+ Angular Material provides a test harness for every component in its library.
12
+
13
+ ## Using a Harness in a Unit Test
14
+
15
+ The `TestbedHarnessEnvironment` is the entry point for using harnesses in unit tests.
16
+
17
+ ### Example: Testing with a `MatButtonHarness`
18
+
19
+ ```ts
20
+ import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
21
+ import {MatButtonHarness} from '@angular/material/button/testing';
22
+ import {MyButtonContainerComponent} from './my-button-container.component';
23
+
24
+ describe('MyButtonContainerComponent', () => {
25
+ let fixture: ComponentFixture<MyButtonContainerComponent>;
26
+ let loader: HarnessLoader;
27
+
28
+ beforeEach(async () => {
29
+ await TestBed.configureTestingModule({
30
+ imports: [MyButtonContainerComponent, MatButtonModule],
31
+ }).compileComponents();
32
+
33
+ fixture = TestBed.createComponent(MyButtonContainerComponent);
34
+ // Create a harness loader for the component's fixture
35
+ loader = TestbedHarnessEnvironment.loader(fixture);
36
+ });
37
+
38
+ it('should find a button with specific text', async () => {
39
+ // Load the harness for a MatButton with the text "Submit"
40
+ const submitButton = await loader.getHarness(MatButtonHarness.with({text: 'Submit'}));
41
+
42
+ // Use the harness API to interact with the component
43
+ expect(await submitButton.isDisabled()).toBe(false);
44
+ await submitButton.click();
45
+
46
+ // ... assertions
47
+ });
48
+ });
49
+ ```
50
+
51
+ ### Key Concepts
52
+
53
+ 1. **`HarnessLoader`**: An object used to find and create harness instances. Get a loader for your component's fixture using `TestbedHarnessEnvironment.loader(fixture)`.
54
+
55
+ 2. **`loader.getHarness(HarnessClass)`**: Asynchronously finds and returns a harness instance for the first matching component.
56
+
57
+ 3. **`HarnessClass.with({ ... })`**: Many harnesses provide a static `with` method that returns a `HarnessPredicate`. This allows you to filter and find components based on their properties, like text, selector, or disabled state. Always use this to precisely target the component you want to test.
58
+
59
+ 4. **Harness API:** Once you have a harness instance, use its methods (e.g., `.click()`, `.getText()`, `.getValue()`) to interact with the component. These methods automatically handle waiting for async operations and change detection.
@@ -0,0 +1,91 @@
1
+ # Component Styling
2
+
3
+ Angular components can define styles that apply specifically to their template, enabling encapsulation and modularity.
4
+
5
+ ## Defining Styles
6
+
7
+ Styles can be defined inline or in separate files.
8
+
9
+ ```ts
10
+ @Component({
11
+ selector: 'app-photo',
12
+ // Inline styles
13
+ styles: `
14
+ img {
15
+ border-radius: 50%;
16
+ }
17
+ `,
18
+ // OR external file
19
+ styleUrl: 'photo.component.css',
20
+ })
21
+ export class Photo {}
22
+ ```
23
+
24
+ ## View Encapsulation
25
+
26
+ Every component has a view encapsulation setting that determines how styles are scoped.
27
+
28
+ | Mode | Behavior |
29
+ | :------------------------------ | :-------------------------------------------------------------------------------------------- |
30
+ | `Emulated` (Default) | Scopes styles to the component using unique HTML attributes. Global styles can still leak in. |
31
+ | `ShadowDom` | Uses the browser's native Shadow DOM API to isolate styles completely. |
32
+ | `None` | Disables encapsulation. Component styles become global. |
33
+ | `ExperimentalIsolatedShadowDom` | Strictly guarantees that only the component's styles apply. |
34
+
35
+ ### Usage
36
+
37
+ ```ts
38
+ import { ViewEncapsulation } from '@angular/core';
39
+
40
+ @Component({
41
+ ...,
42
+ encapsulation: ViewEncapsulation.None,
43
+ })
44
+ export class GlobalStyled {}
45
+ ```
46
+
47
+ ## Special Selectors
48
+
49
+ ### `:host`
50
+
51
+ Targets the component's host element (the element matching the component's selector).
52
+
53
+ ```css
54
+ :host {
55
+ display: block;
56
+ border: 1px solid black;
57
+ }
58
+ ```
59
+
60
+ ### `:host-context()`
61
+
62
+ Targets the host element based on some condition in its ancestry.
63
+
64
+ ```css
65
+ /* Apply styles if any ancestor has the 'theme-dark' class */
66
+ :host-context(.theme-dark) {
67
+ background-color: #333;
68
+ }
69
+ ```
70
+
71
+ ### `::ng-deep`
72
+
73
+ Disables view encapsulation for a specific rule, allowing it to "leak" into child components.
74
+ **Note: The Angular team strongly discourages the use of `::ng-deep`.** It is supported only for backwards compatibility.
75
+
76
+ ## Styles in Templates
77
+
78
+ You can use `<style>` elements directly in a component's template. View encapsulation rules still apply.
79
+
80
+ ```html
81
+ <style>
82
+ .dynamic-class {
83
+ color: red;
84
+ }
85
+ </style>
86
+ <div class="dynamic-class">Hello</div>
87
+ ```
88
+
89
+ ## External Styles
90
+
91
+ Using `<link>` or `@import` in CSS is treated as external styles. **External styles are not affected by emulated view encapsulation.**
@@ -0,0 +1,117 @@
1
+ # Components
2
+
3
+ Angular components are the fundamental building blocks of an application. Each component consists of a TypeScript class with behaviors, an HTML template, and a CSS selector.
4
+
5
+ ## Component Definition
6
+
7
+ Use the `@Component` decorator to define a component's metadata.
8
+
9
+ ```ts
10
+ @Component({
11
+ selector: 'app-profile',
12
+ template: `
13
+ <img src="profile.jpg" alt="Profile photo" />
14
+ <button (click)="save()">Save</button>
15
+ `,
16
+ styles: `
17
+ img {
18
+ border-radius: 50%;
19
+ }
20
+ `,
21
+ })
22
+ export class Profile {
23
+ save() {
24
+ /* ... */
25
+ }
26
+ }
27
+ ```
28
+
29
+ ## Metadata Options
30
+
31
+ - `selector`: The CSS selector that identifies this component in templates.
32
+ - `template`: Inline HTML template (preferred for small templates).
33
+ - `templateUrl`: Path to an external HTML file.
34
+ - `styles`: Inline CSS styles.
35
+ - `styleUrl` / `styleUrls`: Path(s) to external CSS file(s).
36
+ - `imports`: Lists the components, directives, or pipes used in this component's template.
37
+
38
+ ## Using Components
39
+
40
+ To use a component, add it to the `imports` array of the consuming component and use its selector in the template.
41
+
42
+ ```ts
43
+ @Component({
44
+ selector: 'app-root',
45
+ imports: [Profile],
46
+ template: `<app-profile />`,
47
+ })
48
+ export class App {}
49
+ ```
50
+
51
+ ## Template Control Flow
52
+
53
+ Angular uses built-in blocks for conditional rendering and loops.
54
+
55
+ ### Conditional Rendering (`@if`)
56
+
57
+ Use `@if` to conditionally show content. You can include `@else if` and `@else` blocks.
58
+
59
+ ```html
60
+ @if (user.isAdmin) {
61
+ <admin-dashboard />
62
+ } @else if (user.isModerator) {
63
+ <mod-dashboard />
64
+ } @else {
65
+ <standard-dashboard />
66
+ }
67
+ ```
68
+
69
+ **Result aliasing**: Save the result of the expression for reuse.
70
+
71
+ ```html
72
+ @if (user.settings(); as settings) {
73
+ <p>Theme: {{ settings.theme }}</p>
74
+ }
75
+ ```
76
+
77
+ ### Loops (`@for`)
78
+
79
+ The `@for` block iterates over collections. The `track` expression is **required** for performance and DOM reuse.
80
+
81
+ ```html
82
+ <ul>
83
+ @for (item of items(); track item.id; let i = $index, total = $count) {
84
+ <li>{{ i + 1 }}/{{ total }}: {{ item.name }}</li>
85
+ } @empty {
86
+ <li>No items to display.</li>
87
+ }
88
+ </ul>
89
+ ```
90
+
91
+ **Implicit Variables**: `$index`, `$count`, `$first`, `$last`, `$even`, `$odd`.
92
+
93
+ ### Switching Content (`@switch`)
94
+
95
+ The `@switch` block renders content based on a value. It uses strict equality (`===`) and has **no fallthrough**.
96
+
97
+ ```html
98
+ @switch (status()) { @case ('loading') { <app-spinner /> } @case ('error') { <app-error-msg /> }
99
+ @case ('success') { <app-data-grid /> } @default {
100
+ <p>Unknown status</p>
101
+ } }
102
+ ```
103
+
104
+ **Exhaustive Type Checking**: Use `@default never;` to ensure all cases of a union type are handled.
105
+
106
+ ```html
107
+ @switch (state) { @case ('on') { ... } @case ('off') { ... } @default never; // Errors if a new
108
+ state like 'standby' is added }
109
+ ```
110
+
111
+ ## Core Concepts
112
+
113
+ - **Host Element**: The DOM element that matches the component's selector.
114
+ - **View**: The DOM rendered by the component's template inside the host element.
115
+ - **Standalone**: By default, components are standalone (since Angular 19, `standalone: true` is default). For older versions, `standalone: true` must be explicit or the component must be part of an `NgModule`.
116
+ - **Component Tree**: Angular applications are structured as a tree of components, where each component can host child components.
117
+ - **Component Naming**: Do not add suffixes the `Component` suffix for Component classes (e.g., AppComponent) unless the project has been configured to use that naming configuration.
@@ -0,0 +1,97 @@
1
+ # Creating and Using Services
2
+
3
+ Services in Angular are reusable pieces of code that handle data fetching, business logic, or state management that multiple components or other services need to access.
4
+
5
+ ## Creating a Service
6
+
7
+ You can generate a service using the Angular CLI:
8
+
9
+ ```bash
10
+ ng generate service my-data
11
+ ```
12
+
13
+ Or you can manually create a TypeScript class and decorate it with `@Injectable()`.
14
+
15
+ ```ts
16
+ import {Injectable} from '@angular/core';
17
+
18
+ @Injectable({
19
+ providedIn: 'root',
20
+ })
21
+ export class BasicDataStore {
22
+ private data: string[] = [];
23
+
24
+ addData(item: string): void {
25
+ this.data.push(item);
26
+ }
27
+
28
+ getData(): string[] {
29
+ return [...this.data];
30
+ }
31
+ }
32
+ ```
33
+
34
+ ### The `providedIn: 'root'` Option
35
+
36
+ Using `providedIn: 'root'` is the recommended approach for most services. It tells Angular to:
37
+
38
+ - **Create a single instance (singleton)** for the entire application.
39
+ - **Make it available everywhere** automatically, without needing to list it in any `providers` array.
40
+ - **Enable tree-shaking**, meaning the service is only included in the final JavaScript bundle if it is actually injected somewhere.
41
+
42
+ ## Injecting a Service
43
+
44
+ Once a service is created, you can inject it into components, directives, or other services using the `inject()` function.
45
+
46
+ ### Injecting into a Component
47
+
48
+ ```ts
49
+ import {Component, inject} from '@angular/core';
50
+ import {BasicDataStore} from './basic-data-store.service';
51
+
52
+ @Component({
53
+ selector: 'app-example',
54
+ template: `
55
+ <div>
56
+ <p>Data items: {{ dataStore.getData().length }}</p>
57
+ <button (click)="dataStore.addData('New Item')">Add Item</button>
58
+ </div>
59
+ `,
60
+ })
61
+ export class Example {
62
+ // Inject the service as a class field
63
+ dataStore = inject(BasicDataStore);
64
+ }
65
+ ```
66
+
67
+ ### Injecting into Another Service
68
+
69
+ Services can inject other services in the exact same way.
70
+
71
+ ```ts
72
+ import {Injectable, inject} from '@angular/core';
73
+ import {AdvancedDataStore} from './advanced-data-store.service';
74
+
75
+ @Injectable({
76
+ providedIn: 'root',
77
+ })
78
+ export class BasicDataStore {
79
+ // Injecting another service
80
+ private advancedDataStore = inject(AdvancedDataStore);
81
+
82
+ private data: string[] = [];
83
+
84
+ getData(): string[] {
85
+ // Combine data from this service and the injected service
86
+ return [...this.data, ...this.advancedDataStore.getData()];
87
+ }
88
+ }
89
+ ```
90
+
91
+ ## Advanced Service Patterns
92
+
93
+ While `providedIn: 'root'` covers most scenarios, you may sometimes need:
94
+
95
+ - **Component-specific instances**: If a component needs its own isolated instance of a service, provide it directly in the component's `@Component({ providers: [MyService] })` array.
96
+ - **Factory providers**: For dynamic creation.
97
+ - **Value providers**: For injecting configuration objects.
@@ -0,0 +1,69 @@
1
+ # Data Resolvers
2
+
3
+ Data resolvers fetch data before a route activates, ensuring components have the necessary data upon rendering.
4
+
5
+ ## Creating a Resolver
6
+
7
+ Implement the `ResolveFn` type.
8
+
9
+ ```ts
10
+ export const userResolver: ResolveFn<User> = (route, state) => {
11
+ const userService = inject(UserService);
12
+ const id = route.paramMap.get('id')!;
13
+ return userService.getUser(id);
14
+ };
15
+ ```
16
+
17
+ ## Configuring the Route
18
+
19
+ Add the resolver under the `resolve` key.
20
+
21
+ ```ts
22
+ {
23
+ path: 'user/:id',
24
+ component: UserProfile,
25
+ resolve: {
26
+ user: userResolver
27
+ }
28
+ }
29
+ ```
30
+
31
+ ## Accessing Resolved Data
32
+
33
+ ### 1. Via `ActivatedRoute` (Traditional)
34
+
35
+ ```ts
36
+ private route = inject(ActivatedRoute);
37
+ data = toSignal(this.route.data);
38
+ user = computed(() => this.data().user);
39
+ ```
40
+
41
+ ### 2. Via Component Inputs (Modern)
42
+
43
+ Enable `withComponentInputBinding()` in `provideRouter` to pass resolved data directly to `@Input` or `input()`.
44
+
45
+ ```ts
46
+ // app.config.ts
47
+ provideRouter(routes, withComponentInputBinding());
48
+
49
+ // component.ts
50
+ user = input.required<User>();
51
+ ```
52
+
53
+ ## Error Handling
54
+
55
+ Navigation is blocked if a resolver fails.
56
+
57
+ - Use `withNavigationErrorHandler` for global handling.
58
+ - Use `catchError` within the resolver to return a `RedirectCommand` or fallback data.
59
+
60
+ ```ts
61
+ return userService
62
+ .get(id)
63
+ .pipe(catchError(() => of(new RedirectCommand(router.parseUrl('/error')))));
64
+ ```
65
+
66
+ ## Best Practices
67
+
68
+ - **Keep it lightweight**: Fetch only critical data.
69
+ - **Provide feedback**: Listen to router events to show a global loading bar during navigation, as the UI stays on the old page until the resolver finishes.
@@ -0,0 +1,67 @@
1
+ # Define Routes
2
+
3
+ Routes are objects that define which component should render for a specific URL path.
4
+
5
+ ## Basic Configuration
6
+
7
+ Define routes in a `Routes` array and provide them using `provideRouter` in your `appConfig`.
8
+
9
+ ```ts
10
+ // app.routes.ts
11
+ export const routes: Routes = [
12
+ {path: '', component: HomePage},
13
+ {path: 'admin', component: AdminPage},
14
+ ];
15
+
16
+ // app.config.ts
17
+ export const appConfig: ApplicationConfig = {
18
+ providers: [provideRouter(routes)],
19
+ };
20
+ ```
21
+
22
+ ## URL Paths
23
+
24
+ - **Static**: Matches an exact string (e.g., `'admin'`).
25
+ - **Route Parameters**: Dynamic segments prefixed with a colon (e.g., `'user/:id'`).
26
+ - **Wildcard**: Matches any URL using `**`. Useful for "Not Found" pages. **Always place at the end of the array.**
27
+
28
+ ## Matching Strategy
29
+
30
+ Angular uses a **first-match wins** strategy. Specific routes must come before less specific ones.
31
+
32
+ ## Redirects
33
+
34
+ Use `redirectTo` to point one path to another.
35
+
36
+ ```ts
37
+ { path: 'articles', redirectTo: '/blog' },
38
+ { path: 'blog', component: Blog },
39
+ ```
40
+
41
+ ## Page Titles
42
+
43
+ Associate titles with routes for accessibility. Titles can be static or dynamic (via `ResolveFn` or a custom `TitleStrategy`).
44
+
45
+ ```ts
46
+ { path: 'home', component: Home, title: 'Home Page' }
47
+ ```
48
+
49
+ ## Route Data and Providers
50
+
51
+ - **Static Data**: Attach metadata using the `data` property.
52
+ - **Route Providers**: Scope dependencies to a specific route and its children using the `providers` array.
53
+
54
+ ## Nested (Child) Routes
55
+
56
+ Define sub-views using the `children` property. Parent components must include a `<router-outlet />`.
57
+
58
+ ```ts
59
+ {
60
+ path: 'product/:id',
61
+ component: Product,
62
+ children: [
63
+ { path: 'info', component: ProductInfo },
64
+ { path: 'reviews', component: ProductReviews },
65
+ ],
66
+ }
67
+ ```
@@ -0,0 +1,72 @@
1
+ # Defining Dependency Providers
2
+
3
+ Angular offers automatic and manual ways to provide dependencies to its Dependency Injection (DI) system.
4
+
5
+ ## Automatic Provision
6
+
7
+ The most common way to provide a service is using `providedIn: 'root'` on an `@Injectable()`.
8
+
9
+ ### InjectionToken
10
+
11
+ Use `InjectionToken` for non-class dependencies (configuration objects, functions, primitives). An `InjectionToken` can also be automatically provided.
12
+
13
+ ```ts
14
+ import {InjectionToken} from '@angular/core';
15
+
16
+ export interface AppConfig {
17
+ apiUrl: string;
18
+ }
19
+
20
+ export const APP_CONFIG = new InjectionToken<AppConfig>('app.config', {
21
+ providedIn: 'root',
22
+ factory: () => ({apiUrl: 'https://api.example.com'}),
23
+ });
24
+ ```
25
+
26
+ ## Manual Provision
27
+
28
+ You use the `providers` array when a service lacks `providedIn`, when you want a new instance for a specific component, or when configuring runtime values.
29
+
30
+ ```ts
31
+ @Component({
32
+ providers: [
33
+ // Shorthand for { provide: LocalService, useClass: LocalService }
34
+ LocalService,
35
+
36
+ // useClass: Swap implementations
37
+ {provide: Logger, useClass: BetterLogger},
38
+
39
+ // useValue: Provide static values
40
+ {provide: API_URL_TOKEN, useValue: 'https://api.example.com'},
41
+
42
+ // useFactory: Generate value dynamically
43
+ {
44
+ provide: ApiClient,
45
+ useFactory: (http = inject(HttpClient)) => new ApiClient(http),
46
+ },
47
+
48
+ // useExisting: Create an alias
49
+ {provide: OldLogger, useExisting: NewLogger},
50
+
51
+ // multi: Provide multiple values for the same token as an array
52
+ {provide: INTERCEPTOR_TOKEN, useClass: AuthInterceptor, multi: true},
53
+ ],
54
+ })
55
+ export class Example {}
56
+ ```
57
+
58
+ ## Scopes of Providers
59
+
60
+ - **Application Bootstrap**: Global singletons. Use for HTTP clients, logging, or app-wide config.
61
+ - **Component/Directive**: Isolated instances. Use for component-specific state or forms. Services are destroyed when the component is destroyed.
62
+ - **Route**: Feature-specific services loaded only with specific routes.
63
+
64
+ ## Library Pattern: `provide*` functions
65
+
66
+ Library authors should export functions that return provider arrays to encapsulate configuration:
67
+
68
+ ```ts
69
+ export function provideAnalytics(config: AnalyticsConfig): Provider[] {
70
+ return [{provide: ANALYTICS_CONFIG, useValue: config}, AnalyticsService];
71
+ }
72
+ ```