-
+
diff --git a/adev-ja/src/app/features/update/recommendations.en.ts b/adev-ja/src/app/features/update/recommendations.en.ts
index e1ab7b9d4a..5b0f002d70 100644
--- a/adev-ja/src/app/features/update/recommendations.en.ts
+++ b/adev-ja/src/app/features/update/recommendations.en.ts
@@ -2742,4 +2742,12 @@ export const RECOMMENDATIONS: Step[] = [
action:
'In templates parentheses are now always respected. This can lead to runtime breakages when nullish coalescing were nested in parathesis. eg `(foo?.bar).baz` will throw if `foo` is nullish as it would in native JavaScript.',
},
+ {
+ possibleIn: 2000,
+ necessaryAsOf: 2000,
+ level: ApplicationComplexity.Advanced,
+ step: '20.0.0_router_generate_error_redirectTo_and_canMatch_incompatible_together',
+ action:
+ 'Route configurations are now validated more rigorously. Routes that combine `redirectTo` and `canMatch` protections will generate an error, as these properties are incompatible together by default.',
+ },
];
diff --git a/adev-ja/src/app/features/update/recommendations.ts b/adev-ja/src/app/features/update/recommendations.ts
index 484e177702..1843242abe 100644
--- a/adev-ja/src/app/features/update/recommendations.ts
+++ b/adev-ja/src/app/features/update/recommendations.ts
@@ -2742,4 +2742,12 @@ export const RECOMMENDATIONS: Step[] = [
action:
'テンプレートでは括弧が常に尊重されるようになりました。これは、null合体演算子が括弧内にネストされている場合にランタイムエラーを引き起こす可能性があります。例:`(foo?.bar).baz`は、`foo`がnullishの場合、ネイティブJavaScriptと同様にエラーを投げます。',
},
+ {
+ possibleIn: 2000,
+ necessaryAsOf: 2000,
+ level: ApplicationComplexity.Advanced,
+ step: '20.0.0_router_generate_error_redirectTo_and_canMatch_incompatible_together',
+ action:
+ 'ルート設定がより厳密に検証されるようになりました。`redirectTo`と`canMatch`保護を組み合わせたルートはエラーを生成します。これらのプロパティはデフォルトで互いに互換性がないためです。',
+ },
];
diff --git a/adev-ja/src/app/features/update/update.component.en.ts b/adev-ja/src/app/features/update/update.component.en.ts
index 859823f946..1537342506 100644
--- a/adev-ja/src/app/features/update/update.component.en.ts
+++ b/adev-ja/src/app/features/update/update.component.en.ts
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
-import {ChangeDetectionStrategy, Component, HostListener, inject, signal} from '@angular/core';
+import {ChangeDetectionStrategy, Component, inject, signal} from '@angular/core';
import {Step, RECOMMENDATIONS} from './recommendations';
import {Clipboard} from '@angular/cdk/clipboard';
import {CdkMenuModule} from '@angular/cdk/menu';
@@ -26,6 +26,8 @@ interface Option {
description: string;
}
+const isWindows = typeof window !== 'undefined' && window.navigator.userAgent.includes('Windows');
+
@Component({
selector: 'adev-update-guide',
templateUrl: './update.component.html',
@@ -40,6 +42,9 @@ interface Option {
IconComponent,
],
changeDetection: ChangeDetectionStrategy.OnPush,
+ host: {
+ '(click)': 'copyCode($event)',
+ },
})
export default class UpdateComponent {
private readonly snackBar = inject(MatSnackBar);
@@ -50,7 +55,7 @@ export default class UpdateComponent {
protected options: Record = {
ngUpgrade: false,
material: false,
- windows: isWindows(),
+ windows: isWindows,
};
protected readonly optionList: Option[] = [
@@ -128,8 +133,9 @@ export default class UpdateComponent {
}
}
- @HostListener('click', ['$event.target'])
- copyCode({tagName, textContent}: Element) {
+ copyCode(event: Event) {
+ const {tagName, textContent} = event.target as Element;
+
if (tagName === 'CODE') {
this.clipboard.copy(textContent!);
this.snackBar.open('Copied to clipboard', '', {duration: 2000});
@@ -247,7 +253,7 @@ export default class UpdateComponent {
if (this.to.number < 600) {
const actionMessage = `Update all of your dependencies to the latest Angular and the right version of TypeScript.`;
- if (isWindows()) {
+ if (isWindows) {
const packages =
angularPackages
.map((packageName) => `@angular/${packageName}@${angularVersion}`)
@@ -297,13 +303,3 @@ export default class UpdateComponent {
return newAction;
}
}
-
-/** Whether or not the user is running on a Windows OS. */
-function isWindows(): boolean {
- if (typeof navigator === 'undefined') {
- return false;
- }
-
- const platform = navigator.platform.toLowerCase();
- return platform.includes('windows') || platform.includes('win32');
-}
diff --git a/adev-ja/src/app/features/update/update.component.ts b/adev-ja/src/app/features/update/update.component.ts
index 7810f9ac9c..4ff9e7ea94 100644
--- a/adev-ja/src/app/features/update/update.component.ts
+++ b/adev-ja/src/app/features/update/update.component.ts
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
-import {ChangeDetectionStrategy, Component, HostListener, inject, signal} from '@angular/core';
+import {ChangeDetectionStrategy, Component, inject, signal} from '@angular/core';
import {Step, RECOMMENDATIONS} from './recommendations';
import {Clipboard} from '@angular/cdk/clipboard';
import {CdkMenuModule} from '@angular/cdk/menu';
@@ -26,6 +26,8 @@ interface Option {
description: string;
}
+const isWindows = typeof window !== 'undefined' && window.navigator.userAgent.includes('Windows');
+
@Component({
selector: 'adev-update-guide',
templateUrl: './update.component.html',
@@ -40,6 +42,9 @@ interface Option {
IconComponent,
],
changeDetection: ChangeDetectionStrategy.OnPush,
+ host: {
+ '(click)': 'copyCode($event)',
+ },
})
export default class UpdateComponent {
private readonly snackBar = inject(MatSnackBar);
@@ -50,7 +55,7 @@ export default class UpdateComponent {
protected options: Record = {
ngUpgrade: false,
material: false,
- windows: isWindows(),
+ windows: isWindows,
};
protected readonly optionList: Option[] = [
@@ -128,8 +133,8 @@ export default class UpdateComponent {
}
}
- @HostListener('click', ['$event.target'])
- copyCode({tagName, textContent}: Element) {
+ copyCode(event: Event) {
+ const {tagName, textContent} = event.target as Element;
if (tagName === 'CODE') {
this.clipboard.copy(textContent!);
@@ -248,7 +253,7 @@ export default class UpdateComponent {
if (this.to.number < 600) {
const actionMessage = `依存関係をすべて最新のAngularと適切なバージョンのTypeScriptにあわせてアップデートします。`;
- if (isWindows()) {
+ if (isWindows) {
const packages =
angularPackages
.map((packageName) => `@angular/${packageName}@${angularVersion}`)
@@ -298,13 +303,3 @@ export default class UpdateComponent {
return newAction;
}
}
-
-/** Whether or not the user is running on a Windows OS. */
-function isWindows(): boolean {
- if (typeof navigator === 'undefined') {
- return false;
- }
-
- const platform = navigator.platform.toLowerCase();
- return platform.includes('windows') || platform.includes('win32');
-}
diff --git a/adev-ja/src/app/routing/sub-navigation-data.en.ts b/adev-ja/src/app/routing/sub-navigation-data.en.ts
index ad1a5e258d..12d4d84abc 100644
--- a/adev-ja/src/app/routing/sub-navigation-data.en.ts
+++ b/adev-ja/src/app/routing/sub-navigation-data.en.ts
@@ -64,6 +64,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'essentials/templates',
contentPath: 'introduction/essentials/templates',
},
+ {
+ label: 'Forms with signals',
+ path: 'essentials/signal-forms',
+ contentPath: 'introduction/essentials/signal-forms',
+ },
{
label: 'Modular design with dependency injection',
path: 'essentials/dependency-injection',
@@ -282,26 +287,25 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
{
label: 'Dependency Injection',
+ status: 'updated',
children: [
{
label: 'Overview',
path: 'guide/di',
contentPath: 'guide/di/overview',
+ status: 'updated',
},
{
- label: 'Understanding dependency injection',
- path: 'guide/di/dependency-injection',
- contentPath: 'guide/di/dependency-injection',
- },
- {
- label: 'Creating an injectable service',
- path: 'guide/di/creating-injectable-service',
- contentPath: 'guide/di/creating-injectable-service',
+ label: 'Creating and using services',
+ path: 'guide/di/creating-and-using-services',
+ contentPath: 'guide/di/creating-and-using-services',
+ status: 'updated',
},
{
label: 'Defining dependency providers',
- path: 'guide/di/dependency-injection-providers',
- contentPath: 'guide/di/dependency-injection-providers',
+ path: 'guide/di/defining-dependency-providers',
+ contentPath: 'guide/di/defining-dependency-providers',
+ status: 'updated',
},
{
label: 'Injection context',
@@ -416,12 +420,37 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
{
label: 'Forms',
+ status: 'updated',
children: [
{
label: 'Overview',
path: 'guide/forms',
contentPath: 'guide/forms/overview',
},
+ {
+ label: 'Signal forms',
+ status: 'new',
+ children: [
+ {
+ label: 'Overview',
+ path: 'guide/forms/signals/overview',
+ contentPath: 'guide/forms/signals/overview',
+ status: 'new',
+ },
+ {
+ label: 'Form models',
+ path: 'guide/forms/signals/models',
+ contentPath: 'guide/forms/signals/models',
+ status: 'new',
+ },
+ {
+ label: 'Comparison with other form systems',
+ path: 'guide/forms/signals/comparison',
+ contentPath: 'guide/forms/signals/comparison',
+ status: 'new',
+ },
+ ],
+ },
{
label: 'Reactive forms',
path: 'guide/forms/reactive-forms',
@@ -517,16 +546,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing',
contentPath: 'guide/testing/overview',
},
- {
- label: 'Code coverage',
- path: 'guide/testing/code-coverage',
- contentPath: 'guide/testing/code-coverage',
- },
- {
- label: 'Testing services',
- path: 'guide/testing/services',
- contentPath: 'guide/testing/services',
- },
{
label: 'Basics of testing components',
path: 'guide/testing/components-basics',
@@ -537,6 +556,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing/components-scenarios',
contentPath: 'guide/testing/components-scenarios',
},
+ {
+ label: 'Testing services',
+ path: 'guide/testing/services',
+ contentPath: 'guide/testing/services',
+ },
{
label: 'Testing attribute directives',
path: 'guide/testing/attribute-directives',
@@ -558,16 +582,16 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing/debugging',
contentPath: 'guide/testing/debugging',
},
+ {
+ label: 'Code coverage',
+ path: 'guide/testing/code-coverage',
+ contentPath: 'guide/testing/code-coverage',
+ },
{
label: 'Testing utility APIs',
path: 'guide/testing/utility-apis',
contentPath: 'guide/testing/utility-apis',
},
- {
- label: 'Experimental unit testing integration',
- path: 'guide/testing/unit-tests',
- contentPath: 'guide/testing/experimental-unit-test',
- },
{
label: 'Component harnesses overview',
path: 'guide/testing/component-harnesses-overview',
@@ -588,6 +612,87 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing/component-harnesses-testing-environments',
contentPath: 'guide/testing/component-harnesses-testing-environments',
},
+ {
+ label: 'Migrating from Karma to Vitest',
+ path: 'guide/testing/migrating-to-vitest',
+ contentPath: 'guide/testing/migrating-to-vitest',
+ },
+ {
+ label: 'Testing with Karma and Jasmine',
+ path: 'guide/testing/karma',
+ contentPath: 'guide/testing/karma',
+ },
+ ],
+ },
+ {
+ label: 'Angular Aria',
+ status: 'new',
+ children: [
+ {
+ label: 'Overview',
+ path: 'guide/aria/overview',
+ contentPath: 'guide/aria/overview',
+ },
+ {
+ label: 'Accordion',
+ path: 'guide/aria/accordion',
+ contentPath: 'guide/aria/accordion',
+ },
+ {
+ label: 'Autocomplete',
+ path: 'guide/aria/autocomplete',
+ contentPath: 'guide/aria/autocomplete',
+ },
+ {
+ label: 'Combobox',
+ path: 'guide/aria/combobox',
+ contentPath: 'guide/aria/combobox',
+ },
+ {
+ label: 'Grid',
+ path: 'guide/aria/grid',
+ contentPath: 'guide/aria/grid',
+ },
+ {
+ label: 'Listbox',
+ path: 'guide/aria/listbox',
+ contentPath: 'guide/aria/listbox',
+ },
+ {
+ label: 'Menu',
+ path: 'guide/aria/menu',
+ contentPath: 'guide/aria/menu',
+ },
+ {
+ label: 'Menubar',
+ path: 'guide/aria/menubar',
+ contentPath: 'guide/aria/menubar',
+ },
+ {
+ label: 'Multiselect',
+ path: 'guide/aria/multiselect',
+ contentPath: 'guide/aria/multiselect',
+ },
+ {
+ label: 'Select',
+ path: 'guide/aria/select',
+ contentPath: 'guide/aria/select',
+ },
+ {
+ label: 'Tabs',
+ path: 'guide/aria/tabs',
+ contentPath: 'guide/aria/tabs',
+ },
+ {
+ label: 'Toolbar',
+ path: 'guide/aria/toolbar',
+ contentPath: 'guide/aria/toolbar',
+ },
+ {
+ label: 'Tree',
+ path: 'guide/aria/tree',
+ contentPath: 'guide/aria/tree',
+ },
],
},
{
@@ -703,6 +808,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'ai/mcp',
contentPath: 'ai/mcp-server-setup',
},
+ {
+ label: 'Angular AI Tutor',
+ path: 'ai/ai-tutor',
+ contentPath: 'ai/ai-tutor',
+ },
],
},
{
@@ -914,6 +1024,17 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
+ {
+ label: 'Developer Events',
+ children: [
+ {
+ label: 'Angular v21 Release',
+ path: 'events/v21',
+ contentPath: 'events/v21',
+ status: 'new',
+ },
+ ],
+ },
{
label: 'Extended Ecosystem',
children: [
@@ -1431,6 +1552,30 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'reference/migrations/self-closing-tags',
contentPath: 'reference/migrations/self-closing-tags',
},
+ {
+ label: 'NgClass to Class',
+ path: 'reference/migrations/ngclass-to-class',
+ contentPath: 'reference/migrations/ngclass-to-class',
+ status: 'new',
+ },
+ {
+ label: 'NgStyle to Style',
+ path: 'reference/migrations/ngstyle-to-style',
+ contentPath: 'reference/migrations/ngstyle-to-style',
+ status: 'new',
+ },
+ {
+ label: 'Router Testing Module Migration',
+ path: 'reference/migrations/router-testing-module-migration',
+ contentPath: 'reference/migrations/router-testing-module-migration',
+ status: 'new',
+ },
+ {
+ label: 'CommonModule to Standalone',
+ path: 'reference/migrations/common-to-standalone',
+ contentPath: 'reference/migrations/common-to-standalone',
+ status: 'new',
+ },
],
},
];
diff --git a/adev-ja/src/app/routing/sub-navigation-data.ts b/adev-ja/src/app/routing/sub-navigation-data.ts
index 225754d6aa..99f95de295 100644
--- a/adev-ja/src/app/routing/sub-navigation-data.ts
+++ b/adev-ja/src/app/routing/sub-navigation-data.ts
@@ -64,6 +64,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'essentials/templates',
contentPath: 'introduction/essentials/templates',
},
+ {
+ label: 'シグナルを使ったフォーム',
+ path: 'essentials/signal-forms',
+ contentPath: 'introduction/essentials/signal-forms',
+ },
{
label: '依存性の注入によるモジュール設計',
path: 'essentials/dependency-injection',
@@ -282,26 +287,25 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
{
label: '依存性の注入',
+ status: 'updated',
children: [
{
label: '概要',
path: 'guide/di',
contentPath: 'guide/di/overview',
+ status: 'updated',
},
{
- label: '依存性の注入を理解する',
- path: 'guide/di/dependency-injection',
- contentPath: 'guide/di/dependency-injection',
- },
- {
- label: '注入可能なサービスの作成',
- path: 'guide/di/creating-injectable-service',
- contentPath: 'guide/di/creating-injectable-service',
+ label: 'サービスの作成と使用',
+ path: 'guide/di/creating-and-using-services',
+ contentPath: 'guide/di/creating-and-using-services',
+ status: 'updated',
},
{
label: '依存性プロバイダーの定義',
- path: 'guide/di/dependency-injection-providers',
- contentPath: 'guide/di/dependency-injection-providers',
+ path: 'guide/di/defining-dependency-providers',
+ contentPath: 'guide/di/defining-dependency-providers',
+ status: 'updated',
},
{
label: '注入コンテキスト',
@@ -416,12 +420,37 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
{
label: 'フォーム',
+ status: 'updated',
children: [
{
label: '概要',
path: 'guide/forms',
contentPath: 'guide/forms/overview',
},
+ {
+ label: 'Signalフォーム',
+ status: 'new',
+ children: [
+ {
+ label: '概要',
+ path: 'guide/forms/signals/overview',
+ contentPath: 'guide/forms/signals/overview',
+ status: 'new',
+ },
+ {
+ label: 'フォームモデル',
+ path: 'guide/forms/signals/models',
+ contentPath: 'guide/forms/signals/models',
+ status: 'new',
+ },
+ {
+ label: '他のフォームシステムとの比較',
+ path: 'guide/forms/signals/comparison',
+ contentPath: 'guide/forms/signals/comparison',
+ status: 'new',
+ },
+ ],
+ },
{
label: 'リアクティブフォーム',
path: 'guide/forms/reactive-forms',
@@ -517,16 +546,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing',
contentPath: 'guide/testing/overview',
},
- {
- label: 'コードカバレッジ',
- path: 'guide/testing/code-coverage',
- contentPath: 'guide/testing/code-coverage',
- },
- {
- label: 'サービスのテスト',
- path: 'guide/testing/services',
- contentPath: 'guide/testing/services',
- },
{
label: 'コンポーネントのテストの基本',
path: 'guide/testing/components-basics',
@@ -537,6 +556,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing/components-scenarios',
contentPath: 'guide/testing/components-scenarios',
},
+ {
+ label: 'サービスのテスト',
+ path: 'guide/testing/services',
+ contentPath: 'guide/testing/services',
+ },
{
label: '属性ディレクティブのテスト',
path: 'guide/testing/attribute-directives',
@@ -558,16 +582,16 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing/debugging',
contentPath: 'guide/testing/debugging',
},
+ {
+ label: 'コードカバレッジ',
+ path: 'guide/testing/code-coverage',
+ contentPath: 'guide/testing/code-coverage',
+ },
{
label: 'テストユーティリティAPI',
path: 'guide/testing/utility-apis',
contentPath: 'guide/testing/utility-apis',
},
- {
- label: '実験的なユニットテストシステム',
- path: 'guide/testing/unit-tests',
- contentPath: 'guide/testing/experimental-unit-test',
- },
{
label: 'コンポーネントハーネスの概要',
path: 'guide/testing/component-harnesses-overview',
@@ -588,6 +612,87 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing/component-harnesses-testing-environments',
contentPath: 'guide/testing/component-harnesses-testing-environments',
},
+ {
+ label: 'KarmaからVitestへの移行',
+ path: 'guide/testing/migrating-to-vitest',
+ contentPath: 'guide/testing/migrating-to-vitest',
+ },
+ {
+ label: 'KarmaとJasmineによるテスト',
+ path: 'guide/testing/karma',
+ contentPath: 'guide/testing/karma',
+ },
+ ],
+ },
+ {
+ label: 'Angular Aria',
+ status: 'new',
+ children: [
+ {
+ label: '概要',
+ path: 'guide/aria/overview',
+ contentPath: 'guide/aria/overview',
+ },
+ {
+ label: 'Accordion',
+ path: 'guide/aria/accordion',
+ contentPath: 'guide/aria/accordion',
+ },
+ {
+ label: 'Autocomplete',
+ path: 'guide/aria/autocomplete',
+ contentPath: 'guide/aria/autocomplete',
+ },
+ {
+ label: 'Combobox',
+ path: 'guide/aria/combobox',
+ contentPath: 'guide/aria/combobox',
+ },
+ {
+ label: 'Grid',
+ path: 'guide/aria/grid',
+ contentPath: 'guide/aria/grid',
+ },
+ {
+ label: 'Listbox',
+ path: 'guide/aria/listbox',
+ contentPath: 'guide/aria/listbox',
+ },
+ {
+ label: 'Menu',
+ path: 'guide/aria/menu',
+ contentPath: 'guide/aria/menu',
+ },
+ {
+ label: 'Menubar',
+ path: 'guide/aria/menubar',
+ contentPath: 'guide/aria/menubar',
+ },
+ {
+ label: 'Multiselect',
+ path: 'guide/aria/multiselect',
+ contentPath: 'guide/aria/multiselect',
+ },
+ {
+ label: 'Select',
+ path: 'guide/aria/select',
+ contentPath: 'guide/aria/select',
+ },
+ {
+ label: 'Tabs',
+ path: 'guide/aria/tabs',
+ contentPath: 'guide/aria/tabs',
+ },
+ {
+ label: 'Toolbar',
+ path: 'guide/aria/toolbar',
+ contentPath: 'guide/aria/toolbar',
+ },
+ {
+ label: 'Tree',
+ path: 'guide/aria/tree',
+ contentPath: 'guide/aria/tree',
+ },
],
},
{
@@ -703,6 +808,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'ai/mcp',
contentPath: 'ai/mcp-server-setup',
},
+ {
+ label: 'Angular AI Tutor',
+ path: 'ai/ai-tutor',
+ contentPath: 'ai/ai-tutor',
+ },
],
},
{
@@ -914,6 +1024,17 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
+ {
+ label: '開発者向けイベント',
+ children: [
+ {
+ label: 'Angular v21 Release',
+ path: 'events/v21',
+ contentPath: 'events/v21',
+ status: 'new',
+ },
+ ],
+ },
{
label: '拡張エコシステム',
children: [
@@ -946,7 +1067,7 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'guide/animations/reusable-animations',
},
{
- label: 'Migrating to Native CSS Animations',
+ label: 'ネイティブCSSアニメーションへの移行',
path: 'guide/animations/migration',
contentPath: 'guide/animations/migration',
},
@@ -1337,10 +1458,10 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
],
},
{
- label: 'Extended Diagnostics',
+ label: '拡張診断',
children: [
{
- label: 'Overview',
+ label: '概要',
path: 'extended-diagnostics',
contentPath: 'reference/extended-diagnostics/overview',
},
@@ -1410,35 +1531,59 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'reference/migrations/inject-function',
},
{
- label: 'Lazy-loaded routes',
+ label: '遅延読み込みルート',
path: 'reference/migrations/route-lazy-loading',
contentPath: 'reference/migrations/route-lazy-loading',
},
{
- label: 'Signal inputs',
+ label: 'Signal入力',
path: 'reference/migrations/signal-inputs',
contentPath: 'reference/migrations/signal-inputs',
},
{
- label: 'Outputs',
+ label: '出力',
path: 'reference/migrations/outputs',
contentPath: 'reference/migrations/outputs',
},
{
- label: 'Signal queries',
+ label: 'Signalクエリ',
path: 'reference/migrations/signal-queries',
contentPath: 'reference/migrations/signal-queries',
},
{
- label: 'Clean up unused imports',
+ label: '未使用のインポートのクリーンアップ',
path: 'reference/migrations/cleanup-unused-imports',
contentPath: 'reference/migrations/cleanup-unused-imports',
},
{
- label: 'Self-closing tags',
+ label: '自己閉鎖タグ',
path: 'reference/migrations/self-closing-tags',
contentPath: 'reference/migrations/self-closing-tags',
},
+ {
+ label: 'NgClassからClassへ',
+ path: 'reference/migrations/ngclass-to-class',
+ contentPath: 'reference/migrations/ngclass-to-class',
+ status: 'new',
+ },
+ {
+ label: 'NgStyleからStyleへ',
+ path: 'reference/migrations/ngstyle-to-style',
+ contentPath: 'reference/migrations/ngstyle-to-style',
+ status: 'new',
+ },
+ {
+ label: 'Routerテストモジュールのマイグレーション',
+ path: 'reference/migrations/router-testing-module-migration',
+ contentPath: 'reference/migrations/router-testing-module-migration',
+ status: 'new',
+ },
+ {
+ label: 'CommonModuleからスタンドアロンへ',
+ path: 'reference/migrations/common-to-standalone',
+ contentPath: 'reference/migrations/common-to-standalone',
+ status: 'new',
+ },
],
},
];
diff --git a/adev-ja/src/content/ai/ai-tutor.md b/adev-ja/src/content/ai/ai-tutor.md
new file mode 100644
index 0000000000..fd3b01aed9
--- /dev/null
+++ b/adev-ja/src/content/ai/ai-tutor.md
@@ -0,0 +1,150 @@
+# Angular AI Tutor
+
+The Angular AI Tutor is designed to interactively guide you step-by-step through building a complete, modern Angular application from the ground up. You'll learn the latest patterns and best practices by building a real, tangible project: a **"Smart Recipe Box"** for creating and managing recipes.
+
+Our goal is to foster critical thinking and help you retain what you learn. Instead of just giving you code, the tutor will explain concepts, show you examples, and then give you project-specific exercises to solve on your own.
+
+## Get Started
+
+You can access the AI tutor via the [Angular MCP server](ai/mcp).
+
+1. [Install](ai/mcp#get-started) the Angular MCP server
+2. Create a new Angular project `ng new `
+3. Navigate to your new project (`cd `) in an AI-powered editor or tool, like the [Gemini CLI](https://geminicli.com/)
+4. Enter a prompt like `launch the Angular AI tutor`
+ 
+
+## Using the AI Tutor
+
+Each module begins with a brief concept explanation.
+
+If applicable, the tutor will present a code example to demonstrate the concept.
+
+The tutor will also provide an open-ended exercise to test your understanding.
+
+Finally, the tutor will check your work before moving onto the next module.
+
+
+## How It Works: The Learning Cycle
+
+For each new topic, you'll follow a learning loop that emphasizes critical thinking to help you better retain what you learn.
+
+1. **Learn the Concept:** The tutor will briefly explain a core Angular feature and show you a generic code example to illustrate it.
+2. **Apply Your Knowledge:** You'll immediately get a hands-on exercise. The tutor presents these exercises at a high level with objectives and expected outcomes, encouraging you to think through the solution yourself.
+3. **Get Feedback & Support:** When you're ready, let the tutor know. It will **automatically read your project files** to verify your solution is correct. If you get stuck, you are in complete control. You can ask for a **"hint"** for more guidance, or get step-by-step instructions by typing **"detailed guide"** or **"step-by-step instructions."**
+
+Once you've succeeded, the tutor will move directly to the next topic. You can also ask the tutor for more information on a topic or ask any related Angular questions at any time.
+
+---
+
+## **Features & Commands**
+
+You are in control of your learning experience. Use these features at any time:
+
+### **Leave and Come Back**
+
+Feel free to take a break. Your progress is tied to your project's code. When you return for a new session, the tutor will automatically analyze your files to determine exactly where you left off, allowing you to seamlessly pick up right where you were.
+
+**Pro Tip:** We highly recommend using Git to save your progress. After completing a module, it's a great idea to commit your changes (e.g., `git commit -m "Complete Phase 1, Module 8"`). This acts as a personal checkpoint you can always return to.
+
+### **Adjust Your Experience Level**
+
+You can set your experience level to **Beginner (1-3)**, **Intermediate (4-7)**, or **Experienced (8-10)**. You can change this setting at any time during your session, and the tutor will immediately adapt its teaching style to match.
+
+**Example Prompts:**
+
+- "Set my experience level to beginner."
+- "Change my rating to 8."
+
+### **See the Full Learning Plan**
+
+Want to see the big picture or check how far you've come? Just ask for the table of contents.
+
+**Example Prompts:**
+
+- "Where are we?"
+- "Show the table of contents."
+- "Show the plan."
+
+The tutor will display the full learning plan and mark your current location.
+
+### **A Note on Styling**
+
+The tutor will apply basic styling to your application to keep things looking clean. You are highly encouraged to apply your own styling to make the app your own.
+
+### **Skip the Current Module**
+
+If you'd rather move on to the next topic in the learning path, you can ask the tutor to skip the current exercise.
+
+**Example Prompts:**
+
+- "Skip this section."
+- "Auto-complete this step for me."
+
+The tutor will ask for confirmation and then present you with the complete code solution for the current module and attempt to automatically apply any required updates to ensure you can continue smoothly with the next module.
+
+### **Jump to Any Topic**
+
+If you want to learn about a specific topic out of order (e.g., jump from the basics to forms), you can. The tutor will provide the necessary code to update your project to the correct starting point for the selected module and attempt to automatically apply any required updates.
+
+**Example Prompts:**
+
+- "Take me to the forms lesson."
+- "I want to learn about Route Guards now."
+- "Jump to the section on Services."
+
+---
+
+## **Troubleshooting**
+
+If the tutor doesn't respond correctly or you suspect an issue with your application, here are a few things to try:
+
+1. **Type "proceed":** This can often nudge the tutor to continue to the next step in the event it gets stuck.
+2. **Correct the Tutor:** If the tutor is mistaken about your progress (e.g., it says you're on Module 3 but you've completed Module 8), just tell it. For example: _"I'm actually on Module 8."_ The tutor will re-evaluate your code and adjust.
+3. **Verify Your UI:** If you want to confirm what your application's user interface should look like, just ask the tutor. For example: _"What should I see in my UI?"_
+4. **Reload the Browser Window:** A refresh can solve many issues related to your application.
+5. **Hard Restart the Browser:** Errors are sometimes only surfaced in the browser's developer console. A hard restart can help clear underlying issues related to the application.
+6. **Start a New Chat:** You can always start a new chat to remove the existing history and begin fresh. The tutor will read your files to find the latest step you were on.
+
+## **Your Learning Journey: The Phased Path**
+
+You will build your application over a four-phase journey. You can follow this path from start to finish to create a complete, fully-functional Angular application. Each module builds logically upon the last, taking you from the basics to advanced, real-world features.
+
+**A Note on Automated Setup:** Some modules require a setup step, like creating interfaces or mock data. In these cases, the tutor will present you with the code and file instructions. You will be responsible for creating and modifying these files as instructed before the exercise begins.
+
+### **Phase 1: Angular Fundamentals**
+
+- **Module 1:** Getting Started
+- **Module 2:** Dynamic Text with Interpolation
+- **Module 3:** Event Listeners (`(click)`)
+
+### **Phase 2: State and Signals**
+
+- **Module 4:** State Management with Writable Signals (Part 1: `set`)
+- **Module 5:** State Management with Writable Signals (Part 2: `update`)
+- **Module 6:** Computed Signals
+
+### **Phase 3: Component Architecture**
+
+- **Module 7:** Template Binding (Properties & Attributes)
+- **Module 8:** Creating & Nesting Components
+- **Module 9:** Component Inputs with Signals
+- **Module 10:** Styling Components
+- **Module 11:** List Rendering with `@for`
+- **Module 12:** Conditional Rendering with `@if`
+
+### **Phase 4: Advanced Features & Architecture**
+
+- **Module 13:** Two-Way Binding
+- **Module 14:** Services & Dependency Injection (DI)
+- **Module 15:** Basic Routing
+- **Module 16:** Introduction to Forms
+- **Module 17:** Intro to Angular Material
+
+---
+
+## **A Note on AI & Feedback**
+
+This tutor is powered by a Large Language Model (LLM). While we've worked hard to make it an expert, AIs can make mistakes. If you encounter an explanation or code example that seems incorrect, please let us know. You can correct the tutor, and it will use your feedback to adjust its response.
+
+For any technical bugs or feature requests, please [submit an issue](https://github.com/angular/angular-cli/issues).
diff --git a/adev-ja/src/content/ai/design-patterns.en.md b/adev-ja/src/content/ai/design-patterns.en.md
index 75ae54a811..cdcd7530d3 100644
--- a/adev-ja/src/content/ai/design-patterns.en.md
+++ b/adev-ja/src/content/ai/design-patterns.en.md
@@ -40,8 +40,9 @@ storyResource = resource({
You can configure LLM APIs to return structured data. Strongly typing your `resource` to match the expected output from the LLM provides better type safety and editor autocompletion.
To manage state derived from a resource, use a `computed` signal or `linkedSignal`. Because `linkedSignal` [provides access to prior values](guide/signals/linked-signal), it can serve a variety of AI-related use cases, including
- * building a chat history
- * preserving or customizing data that templates display while LLMs generate content
+
+- building a chat history
+- preserving or customizing data that templates display while LLMs generate content
In the example below, `storyParts` is a `linkedSignal` that appends the latest story parts returned from `storyResource` to the existing array of story parts.
@@ -63,10 +64,10 @@ storyParts = linkedSignal({
LLM APIs may be slower and more error-prone than conventional, more deterministic APIs. You can use several Angular features to build a performant and user-friendly interface.
-* **Scoped Loading:** place the `resource` in the component that directly uses the data. This helps limit change detection cycles (especially in zoneless applications) and prevents blocking other parts of your application. If data needs to be shared across multiple components, provide the `resource` from a service.
-* **SSR and Hydration:** use Server-Side Rendering (SSR) with incremental hydration to render the initial page content quickly. You can show a placeholder for the AI-generated content and defer fetching the data until the component hydrates on the client.
-* **Loading State:** use the `resource` `LOADING` [status](guide/signals/resource#resource-status) to show an indicator, like a spinner, while the request is in flight. This status covers both initial loads and reloads.
-* **Error Handling and Retries:** use the `resource` [**`reload()`**](guide/signals/resource#reloading) method as a simple way for users to retry failed requests, may be more prevalent when relying on AI generated content.
+- **Scoped Loading:** place the `resource` in the component that directly uses the data. This helps limit change detection cycles (especially in zoneless applications) and prevents blocking other parts of your application. If data needs to be shared across multiple components, provide the `resource` from a service.
+- **SSR and Hydration:** use Server-Side Rendering (SSR) with incremental hydration to render the initial page content quickly. You can show a placeholder for the AI-generated content and defer fetching the data until the component hydrates on the client.
+- **Loading State:** use the `resource` `LOADING` [status](guide/signals/resource#resource-status) to show an indicator, like a spinner, while the request is in flight. This status covers both initial loads and reloads.
+- **Error Handling and Retries:** use the `resource` [**`reload()`**](guide/signals/resource#reloading) method as a simple way for users to retry failed requests, may be more prevalent when relying on AI generated content.
The following example demonstrates how to create a responsive UI to dynamically display an AI generated image with loading and retry functionality.
@@ -88,8 +89,8 @@ The following example demonstrates how to create a responsive UI to dynamically
}
```
-
## AI patterns in action: streaming chat responses
+
Interfaces often display partial results from LLM-based APIs incrementally as response data arrives. Angular's resource API provides the ability to stream responses to support this type of pattern. The `stream` property of `resource` accepts an asynchronous function you can use to apply updates to a signal value over time. The signal being updated represents the data being streamed.
```ts
diff --git a/adev-ja/src/content/ai/design-patterns.md b/adev-ja/src/content/ai/design-patterns.md
index eafb2df572..0f2e3b3490 100644
--- a/adev-ja/src/content/ai/design-patterns.md
+++ b/adev-ja/src/content/ai/design-patterns.md
@@ -40,8 +40,9 @@ storyResource = resource({
LLM APIを設定して構造化データを返すことができます。`resource`をLLMからの期待される出力に厳密に型付けすることで、より良い型安全性とエディターのオートコンプリートが提供されます。
リソースから派生した状態を管理するには、`computed`シグナルまたは`linkedSignal`を使用します。`linkedSignal`は[以前の値へのアクセスを提供する](guide/signals/linked-signal)ため、以下を含むさまざまなAI関連のユースケースに役立ちます。
- * チャット履歴の構築
- * LLMがコンテンツを生成している間、テンプレートが表示するデータを保持またはカスタマイズする
+
+- チャット履歴の構築
+- LLMがコンテンツを生成している間、テンプレートが表示するデータを保持またはカスタマイズする
以下の例では、`storyParts`は`linkedSignal`であり、`storyResource`から返された最新のストーリーパーツを既存のストーリーパーツの配列に追加します。
@@ -63,10 +64,10 @@ storyParts = linkedSignal({
LLM APIは、従来のより決定論的なAPIよりも低速でエラーが発生しやすい場合があります。Angularのいくつかの機能を使用して、高性能でユーザーフレンドリーなインターフェースを構築できます。
-* **スコープ付きローディング:** データを直接使用するコンポーネントに`resource`を配置します。これにより、変更検知サイクル(特にゾーンレスアプリケーションで)を制限し、アプリケーションの他の部分がブロックされるのを防ぎます。データが複数のコンポーネント間で共有される必要がある場合は、サービスから`resource`を提供します。
-* **SSRとハイドレーション:** インクリメンタルハイドレーションを備えたサーバーサイドレンダリング (SSR) を使用して、初期ページコンテンツを素早くレンダリングします。AI生成コンテンツのプレースホルダーを表示し、コンポーネントがクライアントでハイドレートされるまでデータのフェッチを遅延させることができます。
-* **ローディング状態:** `resource`の`LOADING` [ステータス](guide/signals/resource#resource-status)を使用して、リクエスト処理中にスピナーのようなインジケーターを表示します。このステータスは、初期ロードとリロードの両方をカバーします。
-* **エラー処理と再試行:** `resource`の[**`reload()`**](guide/signals/resource#reloading)メソッドを、ユーザーが失敗したリクエストを再試行する簡単な方法として使用します。これはAI生成コンテンツに依存する場合により頻繁に発生する可能性があります。
+- **スコープ付きローディング:** データを直接使用するコンポーネントに`resource`を配置します。これにより、変更検知サイクル(特にゾーンレスアプリケーションで)を制限し、アプリケーションの他の部分がブロックされるのを防ぎます。データが複数のコンポーネント間で共有される必要がある場合は、サービスから`resource`を提供します。
+- **SSRとハイドレーション:** インクリメンタルハイドレーションを備えたサーバーサイドレンダリング (SSR) を使用して、初期ページコンテンツを素早くレンダリングします。AI生成コンテンツのプレースホルダーを表示し、コンポーネントがクライアントでハイドレートされるまでデータのフェッチを遅延させることができます。
+- **ローディング状態:** `resource`の`LOADING` [ステータス](guide/signals/resource#resource-status)を使用して、リクエスト処理中にスピナーのようなインジケーターを表示します。このステータスは、初期ロードとリロードの両方をカバーします。
+- **エラー処理と再試行:** `resource`の[**`reload()`**](guide/signals/resource#reloading)メソッドを、ユーザーが失敗したリクエストを再試行する簡単な方法として使用します。これはAI生成コンテンツに依存する場合により頻繁に発生する可能性があります。
次の例は、ローディングと再試行機能を備えたAI生成画像を動的に表示するレスポンシブUIを作成する方法を示しています。
@@ -88,8 +89,8 @@ LLM APIは、従来のより決定論的なAPIよりも低速でエラーが発
}
```
-
## AIパターンを実践する: チャット応答のストリーミング {#ai-patterns-in-action-streaming-chat-responses}
+
インターフェースは、LLMベースのAPIからの部分的な結果を、応答データが到着するにつれて段階的に表示することがよくあります。Angularのresource APIは、この種のパターンをサポートするために応答をストリーミングする機能を提供します。`resource`の`stream`プロパティは、時間の経過とともにシグナル値に更新を適用するために使用できる非同期関数を受け入れます。更新されるシグナルは、ストリーミングされるデータを表します。
```ts
diff --git a/adev-ja/src/content/ai/develop-with-ai.en.md b/adev-ja/src/content/ai/develop-with-ai.en.md
index fa7e25216a..4641f6158b 100644
--- a/adev-ja/src/content/ai/develop-with-ai.en.md
+++ b/adev-ja/src/content/ai/develop-with-ai.en.md
@@ -1,45 +1,49 @@
# LLM prompts and AI IDE setup
+
Generating code with large language models (LLMs) is a rapidly growing area of interest for developers. While LLMs are often capable of generating working code it can be a challenge to generate code for consistently evolving frameworks like Angular.
Advanced instructions and prompting are an emerging standard for supporting modern code generation with domain specific details. This section contains curated content and resources to support more accurate code generation for Angular and LLMs.
## Custom Prompts and System Instructions
+
Improve your experience generating code with LLMs by using one of the following custom, domain specific files.
NOTE: These files will be updated on a regular basis staying up to date with Angular's conventions.
Here is a set of instructions to help LLMs generate correct code that follows Angular best practices. This file can be included as system instructions to your AI tooling or included along with your prompt as context.
-
+
-Click here to download the best-practices.md file.
+Click here to download the best-practices.md file.
## Rules Files
+
Several editors, such as Firebase Studio have rules files useful for providing critical context to LLMs.
-| Environment/IDE | Rules File | Installation Instructions |
-|:----------------|:----------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------|
-| Firebase Studio | airules.md | Configure `airules.md` |
-| Copilot powered IDEs | copilot-instructions.md | Configure `.github/copilot-instructions.md` |
-| Cursor | cursor.md | Configure `cursorrules.md` |
-| JetBrains IDEs | guidelines.md | Configure `guidelines.md` |
-| VS Code | .instructions.md | Configure `.instructions.md` |
-| Windsurf | guidelines.md | Configure `guidelines.md` |
+| Environment/IDE | Rules File | Installation Instructions |
+| :------------------- | :--------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Firebase Studio | airules.md | Configure `airules.md` |
+| Copilot powered IDEs | copilot-instructions.md | Configure `.github/copilot-instructions.md` |
+| Cursor | cursor.md | Configure `cursorrules.md` |
+| JetBrains IDEs | guidelines.md | Configure `guidelines.md` |
+| VS Code | .instructions.md | Configure `.instructions.md` |
+| Windsurf | guidelines.md | Configure `guidelines.md` |
## Angular CLI MCP Server setup
+
The Angular CLI includes an experimental [Model Context Protocol (MCP) server](https://modelcontextprotocol.io/) that allows AI assistants in your development environment to interact with the Angular CLI.
[**Learn how to set up the Angular CLI MCP Server**](/ai/mcp)
## Providing Context with `llms.txt`
-`llms.txt` is a proposed standard for websites designed to help LLMs better understand and process their content. The Angular team has developed two versions of this file to help LLMs and tools that use LLMs for code generation to create better modern Angular code.
+`llms.txt` is a proposed standard for websites designed to help LLMs better understand and process their content. The Angular team has developed two versions of this file to help LLMs and tools that use LLMs for code generation to create better modern Angular code.
-* llms.txt - an index file providing links to key files and resources.
-* llms-full.txt - a more robust compiled set of resources describing how Angular works and how to build Angular applications.
+- llms.txt - an index file providing links to key files and resources.
+- llms-full.txt - a more robust compiled set of resources describing how Angular works and how to build Angular applications.
Be sure [to check out the overview page](/ai) for more information on how to integrate AI into your Angular applications.
## Web Codegen Scorer
-The Angular team developed and open-sourced the [Web Codegen Scorer](https://github.com/angular/web-codegen-scorer), a tool to evaluate and score the quality of AI generated web code. You can use this tool to make evidence-based decisions relating to AI-generated code, such as fine-tuning prompts to improve the accuracy of LLM-generated code for Angular. These prompts can be included as system instructions for your AI tooling or as context with your prompt. You can also use this tool to compare the quality of code produced by different models and monitor quality over time as models and agents evolve.
+The Angular team developed and open-sourced the [Web Codegen Scorer](https://github.com/angular/web-codegen-scorer), a tool to evaluate and score the quality of AI generated web code. You can use this tool to make evidence-based decisions relating to AI-generated code, such as fine-tuning prompts to improve the accuracy of LLM-generated code for Angular. These prompts can be included as system instructions for your AI tooling or as context with your prompt. You can also use this tool to compare the quality of code produced by different models and monitor quality over time as models and agents evolve.
diff --git a/adev-ja/src/content/ai/develop-with-ai.md b/adev-ja/src/content/ai/develop-with-ai.md
index 4f561d4d60..c9718591a6 100644
--- a/adev-ja/src/content/ai/develop-with-ai.md
+++ b/adev-ja/src/content/ai/develop-with-ai.md
@@ -1,20 +1,23 @@
# LLMプロンプトとAI IDEセットアップ
+
大規模言語モデル(LLM)によるコード生成は、開発者にとって急速に成長している関心分野です。LLMは動作するコードを生成できることが多い一方で、Angularのような常に進化するフレームワーク向けにコードを生成することは困難な場合があります。
高度な指示とプロンプトは、ドメイン固有の詳細情報を用いた最新のコード生成をサポートするための新たな標準となっています。このセクションには、AngularとLLM向けにより正確なコード生成をサポートする厳選されたコンテンツとリソースが含まれています。
## カスタムプロンプトとシステム指示 {#custom-prompts-and-system-instructions}
+
LLMでコードを生成する体験を向上させるには、以下のカスタムのドメイン固有ファイルを使用してください。
NOTE: これらのファイルは、Angularの規約に準拠するために定期的に更新されます。
これは、LLMがAngularのベストプラクティスに従った正しいコードを生成するのに役立つ一連の指示です。このファイルは、AIツールへのシステム指示として含めることも、プロンプトとともにコンテキストとして含めることもできます。
-
+ここをクリックしてbest-practices.mdファイルをダウンロードしてください。
## ルールファイル {#rules-files}
+
いくつかのエディター(例: Firebase Studio)には、LLMに重要なコンテキストを提供するのに役立つルールファイルがあります。
| 環境/IDE | ルールファイル | インストール手順 |
@@ -27,18 +30,20 @@ NOTE: これらのファイルは、Angularの規約に準拠するために定
| Windsurf | guidelines.md | `guidelines.md`を設定 |
## Angular CLI MCPサーバーのセットアップ {#angular-cli-mcp-server-setup}
+
Angular CLIには、開発環境のAIアシスタントがAngular CLIと連携できるようにする実験的な[Model Context Protocol (MCP)サーバー](https://modelcontextprotocol.io/)が含まれています。
[**Angular CLI MCPサーバーのセットアップ方法を学ぶ**](/ai/mcp)
## llms.txtによるコンテキスト提供 {#providing-context-with-llmstxt}
-`llms.txt`は、LLMがコンテンツをより良く理解し処理できるよう設計されたウェブサイト向けの提案されている標準です。Angularチームは、LLMおよびコード生成にLLMを使用するツールが、より良いモダンなAngularコードを作成できるようにするため、このファイルの2つのバージョンを開発しました。
+`llms.txt`は、LLMがコンテンツをより良く理解し処理できるよう設計されたウェブサイト向けの提案されている標準です。Angularチームは、LLMおよびコード生成にLLMを使用するツールが、より良いモダンなAngularコードを作成できるようにするため、このファイルの2つのバージョンを開発しました。
-* llms.txt - 主要なファイルとリソースへのリンクを提供するインデックスファイル。
-* llms-full.txt - Angularの動作方法とAngularアプリケーションの構築方法を記述した、より堅牢なコンパイル済みリソースセット。
+- llms.txt - 主要なファイルとリソースへのリンクを提供するインデックスファイル。
+- llms-full.txt - Angularの動作方法とAngularアプリケーションの構築方法を記述した、より堅牢なコンパイル済みリソースセット。
AngularアプリケーションにAIを統合する方法に関する詳細情報については、[概要ページ](/ai)もご確認ください。
## Web Codegen Scorer
+
Angularチームは[Web Codegen Scorer](https://github.com/angular/web-codegen-scorer)を開発し、オープンソース化しました。これは、AI生成ウェブコードの品質を評価・スコア化するためのツールです。このツールを使用して、Angular向けにLLM生成コードの精度を向上させるプロンプトの微調整など、AI生成コードに関するエビデンスベースの意思決定を行うことができます。これらのプロンプトは、AIツールのシステム指示として含めたり、プロンプトとともにコンテキストとして含めたりできます。また、このツールを使用して、異なるモデルが生成するコードの品質を比較したり、モデルやエージェントの進化に伴う品質の経時変化を監視したりできます。
diff --git a/adev-ja/src/content/ai/mcp-server-setup.en.md b/adev-ja/src/content/ai/mcp-server-setup.en.md
index d51831b29d..c4451d50a3 100644
--- a/adev-ja/src/content/ai/mcp-server-setup.en.md
+++ b/adev-ja/src/content/ai/mcp-server-setup.en.md
@@ -6,11 +6,22 @@ The Angular CLI includes an experimental [Model Context Protocol (MCP) server](h
The Angular CLI MCP server provides several tools to assist you in your development workflow. By default, the following tools are enabled:
-| Name | Description | `local-only` | `read-only` |
-| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------: | :---------: |
-| `get_best_practices` | Retrieves the Angular Best Practices Guide. This guide is essential for ensuring that all code adheres to modern standards, including standalone components, typed forms, and modern control flow. | ✅ | ✅ |
-| `list_projects` | Lists the names of all applications and libraries defined within an Angular workspace. It reads the `angular.json` configuration file to identify the projects. | ✅ | ✅ |
-| `search_documentation` | Searches the official Angular documentation at https://angular.dev. This tool should be used to answer any questions about Angular, such as for APIs, tutorials, and best practices. | ❌ | ✅ |
+| Name | Description | `local-only` | `read-only` |
+| :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------: | :---------: |
+| `ai_tutor` | Launches an interactive AI-powered Angular tutor. Recommended to run from a new Angular project using v20 or later. [Learn more](ai/ai-tutor). | ✅ | ✅ |
+| `find_examples` | Finds authoritative code examples from a curated database of official, best-practice examples, focusing on **modern, new, and recently updated** Angular features. | ✅ | ✅ |
+| `get_best_practices` | Retrieves the Angular Best Practices Guide. This guide is essential for ensuring that all code adheres to modern standards, including standalone components, typed forms, and modern control flow. | ✅ | ✅ |
+| `list_projects` | Lists the names of all applications and libraries defined within an Angular workspace. It reads the `angular.json` configuration file to identify the projects. | ✅ | ✅ |
+| `onpush-zoneless-migration` | Analyzes Angular code and provides a step-by-step, iterative plan to migrate it to `OnPush` change detection, a prerequisite for a zoneless application. | ✅ | ✅ |
+| `search_documentation` | Searches the official Angular documentation at . This tool should be used to answer any questions about Angular, such as for APIs, tutorials, and best practices. | ❌ | ✅ |
+
+### Experimental Tools
+
+Some tools are provided in experimental / preview status since they are new or not fully tested. Enable them individually with the [`--experimental-tool`](#command-options) option and use them with caution.
+
+| Name | Description | `local-only` | `read-only` |
+| :---------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------: | :---------: |
+| `modernize` | Performs code migrations and provides further instructions on how to modernize Angular code to align with the latest best practices and syntax. [Learn more](https://angular.dev/reference/migrations) | ✅ | ❌ |
## Get Started
@@ -69,20 +80,21 @@ Create a file named `.gemini/settings.json` in your project's root and add the f
### JetBrains IDEs
-In JetBrains IDEs (like IntelliJ IDEA or WebStorm), after installing the JetBrains AI Assistant plugin, go to `Settings | Tools | AI Assistant | Model Context Protocol (MCP)`. Add a new server and select `As JSON`. Paste the following configuration, which does not use a top-level property for the server list.
+In JetBrains IDEs (like IntelliJ IDEA or WebStorm), after installing the JetBrains AI Assistant plugin, go to `Settings | Tools | AI Assistant | Model Context Protocol (MCP)`. Add a new server (`+`) and select `As JSON`. Then paste the following configuration:
```json
{
- "name": "Angular CLI",
- "command": "npx",
- "args": [
- "-y",
- "@angular/cli",
- "mcp"
- ]
+ "mcpServers": {
+ "angular-cli": {
+ "command": "npx",
+ "args": ["-y", "@angular/cli", "mcp"]
+ }
+ }
}
```
+For the most up-to-date instructions on configuring MCP servers, please refer to the JetBrains documentation: [Connect to an MCP server](https://www.jetbrains.com/help/ai-assistant/mcp.html#connect-to-an-mcp-server).
+
### VS Code
In your project's root, create a file named `.vscode/mcp.json` and add the following configuration. Note the use of the `servers` property.
@@ -117,11 +129,11 @@ For other IDEs, check your IDE's documentation for the proper location of the MC
The `mcp` command can be configured with the following options passed as arguments in your IDE's MCP configuration:
-| Option | Type | Description | Default |
-| :------------- | :-------- | :--------------------------------------------------------------------------------------------------------- | :------ |
-| `--read-only` | `boolean` | Only register tools that do not make changes to the project. Your editor or coding agent may still perform edits. | `false` |
-| `--local-only` | `boolean` | Only register tools that do not require an internet connection. Your editor or coding agent may still send data over the network. | `false` |
-
+| Option | Type | Description | Default |
+| :---------------------------- | :-------- | :-------------------------------------------------------------------------------------------------------------------------------- | :------ |
+| `--read-only` | `boolean` | Only register tools that do not make changes to the project. Your editor or coding agent may still perform edits. | `false` |
+| `--local-only` | `boolean` | Only register tools that do not require an internet connection. Your editor or coding agent may still send data over the network. | `false` |
+| `--experimental-tool` `-E` | `string` | Enable an [experimental tool](#experimental-tools). Separate multiple options by spaces, e.g. `-E tool_a tool_b`. | |
For example, to run the server in read-only mode in VS Code, you would update your `mcp.json` like this:
@@ -138,4 +150,4 @@ For example, to run the server in read-only mode in VS Code, you would update yo
## Feedback and New Ideas
-The Angular team welcomes your feedback on the existing MCP capabilities and any ideas you have for new tools or features. Please share your thoughts by opening an issue on the [angular/angular GitHub repository](https://github.com/angular/angular/issues).
\ No newline at end of file
+The Angular team welcomes your feedback on the existing MCP capabilities and any ideas you have for new tools or features. Please share your thoughts by opening an issue on the [angular/angular GitHub repository](https://github.com/angular/angular/issues).
diff --git a/adev-ja/src/content/ai/mcp-server-setup.md b/adev-ja/src/content/ai/mcp-server-setup.md
index 58fee6634a..ab8a840453 100644
--- a/adev-ja/src/content/ai/mcp-server-setup.md
+++ b/adev-ja/src/content/ai/mcp-server-setup.md
@@ -2,17 +2,28 @@
Angular CLIには、開発環境のAIアシスタントがAngular CLIと対話できるようにする実験的な[Model Context Protocol (MCP) サーバー](https://modelcontextprotocol.io/)が含まれています。CLIによるコード生成、パッケージの追加などに対応しています。
-## 利用可能なツール
+## 利用可能なツール {#available-tools}
Angular CLI MCPサーバーは、開発ワークフローを支援するいくつかのツールを提供します。デフォルトで、以下のツールが有効になっています:
-| 名前 | 説明 | `local-only` | `read-only` |
-| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------: | :---------: |
-| `get_best_practices` | Angularベストプラクティスガイドを取得します。このガイドは、スタンドアロンコンポーネント、型付きフォーム、モダンな制御フローなど、すべてのコードが現代的な標準に準拠することを保証するために不可欠です。 | ✅ | ✅ |
-| `list_projects` | Angularワークスペース内で定義されたすべてのアプリケーションとライブラリの名前を一覧表示します。`angular.json`設定ファイルを読み取ってプロジェクトを識別します。 | ✅ | ✅ |
-| `search_documentation` | https://angular.dev の公式Angularドキュメントを検索します。このツールは、API、チュートリアル、ベストプラクティスなど、Angularに関する質問に答えるために使用する必要があります。 | ❌ | ✅ |
+| 名前 | 説明 | `local-only` | `read-only` |
+| :-------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------: | :---------: |
+| `ai_tutor` | インタラクティブなAI駆動のAngularチューターを起動します。v20以降を使用する新しいAngularプロジェクトから実行することを推奨します。[詳細を見る](ai/ai-tutor)。 | ✅ | ✅ |
+| `find_examples` | 公式のベストプラクティス例の厳選されたデータベースから、権威ある コード例を検索します。**モダンで新しい、最近更新された**Angular機能に焦点を当てています。 | ✅ | ✅ |
+| `get_best_practices` | Angularベストプラクティスガイドを取得します。このガイドは、スタンドアロンコンポーネント、型付きフォーム、モダンな制御フローなど、すべてのコードが現代的な標準に準拠することを保証するために不可欠です。 | ✅ | ✅ |
+| `list_projects` | Angularワークスペース内で定義されたすべてのアプリケーションとライブラリの名前を一覧表示します。`angular.json`設定ファイルを読み取ってプロジェクトを識別します。 | ✅ | ✅ |
+| `onpush-zoneless-migration` | Angularコードを分析し、ゾーンレスアプリケーションの前提条件である`OnPush`変更検知に移行するための段階的で反復的な計画を提供します。 | ✅ | ✅ |
+| `search_documentation` | の公式Angularドキュメントを検索します。このツールは、API、チュートリアル、ベストプラクティスなど、Angularに関する質問に答えるために使用する必要があります。 | ❌ | ✅ |
-## 開始方法
+### 実験的ツール {#experimental-tools}
+
+一部のツールは、新しいまたは完全にテストされていないため、実験的/プレビューステータスで提供されています。[`--experimental-tool`](#command-options)オプションを使用して個別に有効化し、注意して使用してください。
+
+| 名前 | 説明 | `local-only` | `read-only` |
+| :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------: | :---------: |
+| `modernize` | コード移行を実行し、最新のベストプラクティスと構文に合わせてAngularコードをモダナイズする方法についてさらなる指示を提供します。[詳細を見る](https://angular.dev/reference/migrations) | ✅ | ❌ |
+
+## 開始方法 {#get-started}
開始するには、ターミナルで次のコマンドを実行します。
@@ -69,20 +80,21 @@ ng mcp
### JetBrains IDEs
-JetBrains IDEs(IntelliJ IDEAやWebStormなど)では、JetBrains AI Assistantプラグインをインストールした後、`Settings | Tools | AI Assistant | Model Context Protocol (MCP)`に移動します。新しいサーバーを追加し、`As JSON`を選択します。サーバーリストにトップレベルプロパティを使用しない以下の設定を貼り付けます。
+JetBrains IDEs(IntelliJ IDEAやWebStormなど)では、JetBrains AI Assistantプラグインをインストールした後、`Settings | Tools | AI Assistant | Model Context Protocol (MCP)`に移動します。新しいサーバー(`+`)を追加し、`As JSON`を選択します。次に、以下の設定を貼り付けます:
```json
{
- "name": "Angular CLI",
- "command": "npx",
- "args": [
- "-y",
- "@angular/cli",
- "mcp"
- ]
+ "mcpServers": {
+ "angular-cli": {
+ "command": "npx",
+ "args": ["-y", "@angular/cli", "mcp"]
+ }
+ }
}
```
+MCPサーバーの設定に関する最新の手順については、JetBrainsのドキュメントを参照してください:[MCPサーバーに接続する](https://www.jetbrains.com/help/ai-assistant/mcp.html#connect-to-an-mcp-server)。
+
### VS Code
プロジェクトのルートに`.vscode/mcp.json`という名前のファイルを作成し、以下の設定を追加します。`servers`プロパティの使用に注意してください。
@@ -113,15 +125,15 @@ JetBrains IDEs(IntelliJ IDEAやWebStormなど)では、JetBrains AI Assistan
}
```
-## コマンドオプション
+## コマンドオプション {#command-options}
`mcp`コマンドは、IDEのMCP設定で引数として渡される以下のオプションで設定できます:
-| オプション | 型 | 説明 | デフォルト |
-| :------------- | :-------- | :--------------------------------------------------------------------------------------------------------- | :------ |
-| `--read-only` | `boolean` | プロジェクトに変更を加えないツールのみを登録します。エディタまたはコーディングエージェントは引き続き編集を実行する場合があります。 | `false` |
-| `--local-only` | `boolean` | インターネット接続を必要としないツールのみを登録します。エディタまたはコーディングエージェントは引き続きネットワーク経由でデータを送信する場合があります。 | `false` |
-
+| オプション | 型 | 説明 | デフォルト |
+| :---------------------------- | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------- | :--------- |
+| `--read-only` | `boolean` | プロジェクトに変更を加えないツールのみを登録します。エディタまたはコーディングエージェントは引き続き編集を実行する場合があります。 | `false` |
+| `--local-only` | `boolean` | インターネット接続を必要としないツールのみを登録します。エディタまたはコーディングエージェントは引き続きネットワーク経由でデータを送信する場合があります。 | `false` |
+| `--experimental-tool` `-E` | `string` | [実験的ツール](#experimental-tools)を有効にします。複数のオプションをスペースで区切ります。例: `-E tool_a tool_b`。 | |
たとえば、VS Codeにおいて読み取り専用モードでサーバーを実行する場合は、`mcp.json`を次のように更新します:
@@ -136,6 +148,6 @@ JetBrains IDEs(IntelliJ IDEAやWebStormなど)では、JetBrains AI Assistan
}
```
-## フィードバックと新しいアイデア
+## フィードバックと新しいアイデア {#feedback-and-new-ideas}
-Angularチームは、既存のMCP機能に対するフィードバックや新しいツールまたは機能のアイデアを歓迎します。[angular/angular GitHubリポジトリ](https://github.com/angular/angular/issues)でissueを作成して、ご意見をお聞かせください。
\ No newline at end of file
+Angularチームは、既存のMCP機能に対するフィードバックや新しいツールまたは機能のアイデアを歓迎します。[angular/angular GitHubリポジトリ](https://github.com/angular/angular/issues)でissueを作成して、ご意見をお聞かせください。
diff --git a/adev-ja/src/content/ai/overview.en.md b/adev-ja/src/content/ai/overview.en.md
index 33314b886a..e2da24e392 100644
--- a/adev-ja/src/content/ai/overview.en.md
+++ b/adev-ja/src/content/ai/overview.en.md
@@ -1,4 +1,5 @@
+
Build AI-powered apps. Develop faster with AI.
@@ -9,9 +10,9 @@ Generative AI (GenAI) with large language models (LLMs) enables the creation of
Developing features like these would have previously required deep domain expertise and significant engineering effort. However, new products and SDKs are lowering the barrier to entry. Angular is well-suited for integrating AI into your web application as a result of:
-* Angular's robust templating APIs enable the creation of dynamic, cleanly composed UIs made from generated content
-* Strong, signal-based architecture designed to dynamically manage data and state
-* Angular integrates seamlessly with AI SDKs and APIs
+- Angular's robust templating APIs enable the creation of dynamic, cleanly composed UIs made from generated content
+- Strong, signal-based architecture designed to dynamically manage data and state
+- Angular integrates seamlessly with AI SDKs and APIs
This guide demonstrates how you can use [Genkit](/ai#build-ai-powered-applications-with-genkit-and-angular), [Firebase AI Logic](/ai#build-ai-powered-applications-with-firebase-ai-logic-and-angular), and the [Gemini API](/ai#build-ai-powered-applications-with-gemini-api-and-angular) to infuse your Angular apps with AI today. This guide will jumpstart your AI-powered web app development journey by explaining how to begin integrating AI into Angular apps. This guide also shares resources, such as starter kits, example code, and recipes for common workflows, you can use to get up to speed quickly.
@@ -20,77 +21,93 @@ To get started, you should have a basic understanding of Angular. New to Angular
NOTE: While this page features integrations and examples with Google AI products, tools like Genkit are model agnostic and allow you to choose your own model. In many cases, the examples and code samples are applicable to other third-party solutions.
## Getting Started
+
Building AI-powered applications is a new and rapidly developing field. It can be challenging to decide where to start and which technologies to choose. The following section provides three options to choose from:
-1. *Genkit* gives you the choice of [supported model and interface with a unified API](https://genkit.dev) for building full-stack applications. Ideal for applications requiring sophisticated back-end AI logic, such as personalized recommendations.
+1. _Genkit_ gives you the choice of [supported model and interface with a unified API](https://genkit.dev) for building full-stack applications. Ideal for applications requiring sophisticated back-end AI logic, such as personalized recommendations.
-1. *Firebase AI Logic* provides a secure client-side API for Google's models to build client-side only applications or mobile apps. Best for interactive AI features directly in the browser, such as real-time text analysis or basic chatbots.
+1. _Firebase AI Logic_ provides a secure client-side API for Google's models to build client-side only applications or mobile apps. Best for interactive AI features directly in the browser, such as real-time text analysis or basic chatbots.
-1. *Gemini API* enables you to build an application that uses the methods and functionality exposed through the API surface directly, best for full-stack applications. Suitable for applications needing direct control over AI models, like custom image generation or deep data processing.
+1. _Gemini API_ enables you to build an application that uses the methods and functionality exposed through the API surface directly, best for full-stack applications. Suitable for applications needing direct control over AI models, like custom image generation or deep data processing.
### Build AI-powered applications with Genkit and Angular
-[Genkit](https://genkit.dev) is an open-source toolkit designed to help you build AI-powered features in web and mobile apps. It offers a unified interface for integrating AI models from Google, OpenAI, Anthropic, Ollama, and more, so you can explore and choose the best models for your needs. As a server-side solution, your web apps need a supported server environment, such as a node-based server in order to integrate with Genkit. Building a full-stack app using Angular SSR gives you the starting server-side code, for example.
+
+[Genkit](https://genkit.dev) is an open-source toolkit designed to help you build AI-powered features in web and mobile apps. It offers a unified interface for integrating AI models from Google, OpenAI, Anthropic, Ollama, and more, so you can explore and choose the best models for your needs. As a server-side solution, your web apps need a supported server environment, such as a node-based server in order to integrate with Genkit. Building a full-stack app using Angular SSR gives you the starting server-side code, for example.
Here are examples of how to build with Genkit and Angular:
-* [Agentic Apps with Genkit and Angular starter-kit](https://github.com/angular/examples/tree/main/genkit-angular-starter-kit)— New to building with AI? Start here with a basic app that features an agentic workflow. Perfect place to start for your first AI building experience.
+- [Agentic Apps with Genkit and Angular starter-kit](https://github.com/angular/examples/tree/main/genkit-angular-starter-kit) — New to building with AI? Start here with a basic app that features an agentic workflow. Perfect place to start for your first AI building experience.
-* [Use Genkit in an Angular app](https://genkit.dev/docs/angular/)— Build a basic application that uses Genkit Flows, Angular and Gemini 2.5 Flash. This step-by-step walkthrough guides you through creating a full-stack Angular application with AI features.
+- [Use Genkit in an Angular app](https://genkit.dev/docs/angular/) — Build a basic application that uses Genkit Flows, Angular and Gemini 2.5 Flash. This step-by-step walkthrough guides you through creating a full-stack Angular application with AI features.
-* [Dynamic Story Generator app](https://github.com/angular/examples/tree/main/genkit-angular-story-generator)— Learn to build an agentic Angular app powered by Genkit, Gemini and Imagen 3 to dynamically generate a story based on user interaction featuring beautiful image panels to accompany the events that take place. Start here if you'd like to experiment with a more advanced use-case.
+- [Dynamic Story Generator app](https://github.com/angular/examples/tree/main/genkit-angular-story-generator) — Learn to build an agentic Angular app powered by Genkit, Gemini and Imagen 3 to dynamically generate a story based on user interaction featuring beautiful image panels to accompany the events that take place. Start here if you'd like to experiment with a more advanced use-case.
This example also has an in-depth video walkthrough of the functionality:
- * [Watch "Building Agentic Apps with Angular and Genkit live!"](https://youtube.com/live/mx7yZoIa2n4?feature=share)
- * [Watch "Building Agentic Apps with Angular and Genkit live! PT 2"](https://youtube.com/live/YR6LN5_o3B0?feature=share)
+ - [Watch "Building Agentic Apps with Angular and Genkit live!"](https://youtube.com/live/mx7yZoIa2n4?feature=share)
+ - [Watch "Building Agentic Apps with Angular and Genkit live! PT 2"](https://youtube.com/live/YR6LN5_o3B0?feature=share)
+
+- [Building Agentic apps with Firebase and Google Cloud (Barista Example)](https://developers.google.com/solutions/learn/agentic-barista) - Learn how to build an agentic coffee ordering app with Firebase and Google Cloud. This example uses both Firebase AI Logic and Genkit.
-* [Building Agentic apps with Firebase and Google Cloud (Barista Example)](https://developers.google.com/solutions/learn/agentic-barista) - Learn how to build an agentic coffee ordering app with Firebase and Google Cloud. This example uses both Firebase AI Logic and Genkit.
+- [Creating Dynamic, Server-Driven UIs](https://github.com/angular/examples/tree/main/dynamic-sdui-app) - Learn to build Agentic Angular apps with UI views that are generated at runtime based on user input.
+
+ This example also has an in-depth video walkthrough of the functionality:
+ - [Watch "Exploring the future of web apps"](https://www.youtube.com/live/4qargCqOu70?feature=share)
### Build AI-powered applications with Firebase AI Logic and Angular
+
[Firebase AI Logic](https://firebase.google.com/products/vertex-ai-in-firebase) provides a secure way to interact with Vertex AI Gemini API or Imagen API directly from your web and mobile apps. This is compelling for Angular developers since apps can be either full-stack or client-side only. If you are developing a client-side only application, Firebase AI Logic is a good fit for incorporating AI into your web apps.
Here is an example of how to build with Firebase AI Logic and Angular:
-* [Firebase AI Logic x Angular Starter Kit](https://github.com/angular/examples/tree/main/vertex-ai-firebase-angular-example) - Use this starter-kit to build an e-commerce application with a chat agent that can perform tasks. Start here if you do not have experience building with Firebase AI Logic and Angular.
+
+- [Firebase AI Logic x Angular Starter Kit](https://github.com/angular/examples/tree/main/vertex-ai-firebase-angular-example) - Use this starter-kit to build an e-commerce application with a chat agent that can perform tasks. Start here if you do not have experience building with Firebase AI Logic and Angular.
This example includes an [in-depth video walkthrough explaining the functionality and demonstrates how to add new features](https://youtube.com/live/4vfDz2al_BI).
### Build AI-powered applications with Gemini API and Angular
+
The [Gemini API](https://ai.google.dev/gemini-api/docs) provides access to state-of-the-art models from Google that support audio, images, video, and text input. These models that are optimized for specific use cases, [learn more on the Gemini API documentation site](https://ai.google.dev/gemini-api/docs/models).
-* [AI Text Editor Angular app template](https://github.com/FirebaseExtended/firebase-framework-tools/tree/main/starters/angular/ai-text-editor) - Use this template to start with a fully functioning text editor with AI-powered features like refining text, expanding text and formalizing text. This is a good starting point to gain experience with calling the Gemini API via HTTP.
+- [AI Text Editor Angular app template](https://github.com/FirebaseExtended/firebase-framework-tools/tree/main/starters/angular/ai-text-editor) - Use this template to start with a fully functioning text editor with AI-powered features like refining text, expanding text and formalizing text. This is a good starting point to gain experience with calling the Gemini API via HTTP.
-* [AI Chatbot app template](https://github.com/FirebaseExtended/firebase-framework-tools/tree/main/starters/angular/ai-chatbot) - This template starts with a chatbot user interface that communicates with the Gemini API via HTTP.
+- [AI Chatbot app template](https://github.com/FirebaseExtended/firebase-framework-tools/tree/main/starters/angular/ai-chatbot) - This template starts with a chatbot user interface that communicates with the Gemini API via HTTP.
## Best Practices
+
### Connecting to model providers and keeping your API Credentials Secure
-When connecting to model providers, it is important to keep your API secrets safe. *Never put your API key in a file that ships to the client, such as `environments.ts`*.
+
+When connecting to model providers, it is important to keep your API secrets safe. _Never put your API key in a file that ships to the client, such as `environments.ts`_.
Your application's architecture determines which AI APIs and tools to choose. Specifically, choose based on whether or not your application is client-side or server-side. Tools such as Firebase AI Logic provide a secure connection to the model APIs for client-side code. If you want to use a different API than Firebase AI Logic or prefer to use a different model provider, consider creating a proxy-server or even [Cloud Functions for Firebase](https://firebase.google.com/docs/functions) to serve as a proxy and not expose your API keys.
-For an example of connecting using a client-side app, see the code: [Firebase AI Logic Angular example repository](https://github.com/angular/examples/tree/main/vertex-ai-firebase-angular-example).
+For an example of connecting using a client-side app, see the code: [Firebase AI Logic Angular example repository](https://github.com/angular/examples/tree/main/vertex-ai-firebase-angular-example).
For server-side connections to model APIs that require API keys, prefer using a secrets manager or environment variable, not `environments.ts`. You should follow standard best practices for securing API keys and credentials. Firebase now provides a new secrets manager with the latest updates from Firebase App Hosting. To learn more, [check out the official documentation](https://firebase.google.com/docs/app-hosting/configure).
For a server-side connection example in a full-stack application, see the code: [Angular AI Example (Genkit and Angular Story Generator) repository](https://github.com/angular/examples/tree/main/genkit-angular-story-generator).
### Use Tool Calling to enhance apps
+
If you want to build agentic workflows, where agents are able to act and use tools to solve problems based on prompts use "tool calling". Tool calling, also known as function calling, is a way to provide LLMs the ability to make requests back to the application that called it. As a developer, you define which tools are available and you are in control of how or when the tools are called.
-Tool calling further enhances your web apps by expanding your AI integration further than a question and answer style chat bot. In fact, you can empower your model to request function calls using the function calling API of your model provider. The available tools can be used to perform more complex actions within the context of your application.
+Tool calling further enhances your web apps by expanding your AI integration further than a question and answer style chat bot. In fact, you can empower your model to request function calls using the function calling API of your model provider. The available tools can be used to perform more complex actions within the context of your application.
In the [e-commerce example](https://github.com/angular/examples/blob/main/vertex-ai-firebase-angular-example/src/app/ai.service.ts#L88) of the [Angular examples repository](https://github.com/angular/examples), the LLM requests to make calls to functions for inventory in order to gain the necessary context to perform more complex tasks such as calculating how much a group of items in the store will cost. The scope of the available API is up to you as a developer just as is whether or not to call a function requested by the LLM. You remain in control of the flow of execution. You can expose specific functions of a service for example but not all functions of that service.
### Handling non-deterministic responses
+
Because models can return non-deterministic results, your applications should be designed with that in mind. Here are a few strategies that you can use in your application implementation:
-* Adjust prompts and model parameters (such as [temperature](https://ai.google.dev/gemini-api/docs/prompting-strategies)) for more or less deterministic responses. You can [find out more in the prompting strategies section](https://ai.google.dev/gemini-api/docs/prompting-strategies) of [ai.google.dev](https://ai.google.dev/).
-* Use the "human in the loop" strategy where a human verifies outputs before proceeding in a workflow. Build your application workflows to allow operators (humans or other models) to verify outputs and confirm key decisions.
-* Employ tool (or function) calling and schema constraints to guide and restrict model responses to predefined formats, increasing response predictability.
+
+- Adjust prompts and model parameters (such as [temperature](https://ai.google.dev/gemini-api/docs/prompting-strategies)) for more or less deterministic responses. You can [find out more in the prompting strategies section](https://ai.google.dev/gemini-api/docs/prompting-strategies) of [ai.google.dev](https://ai.google.dev/).
+- Use the "human in the loop" strategy where a human verifies outputs before proceeding in a workflow. Build your application workflows to allow operators (humans or other models) to verify outputs and confirm key decisions.
+- Employ tool (or function) calling and schema constraints to guide and restrict model responses to predefined formats, increasing response predictability.
Even considering these strategies and techniques, sensible fallbacks should be incorporated in your application design. Follow existing standards of application resiliency. For example, it is not acceptable for an application to crash if a resource or API is not available. In that scenario, an error message is displayed to the user and, if applicable, options for next steps are also displayed. Building AI-powered applications requires the same consideration. Confirm that the response is aligned with the expected output and provide a "safe landing" in case it is not aligned by way of [graceful degradation](https://developer.mozilla.org/en-US/docs/Glossary/Graceful_degradation). This also applies to API outages for LLM providers.
Consider this example: The LLM provider is not responding. A potential strategy to handle the outage is:
-* Save the response from the user to use in a retry scenario (now or at a later time)
-* Alert the user to the outage with an appropriate message that doesn't reveal sensitive information
-* Resume the conversation at a later time once the services are available again.
+
+- Save the response from the user to use in a retry scenario (now or at a later time)
+- Alert the user to the outage with an appropriate message that doesn't reveal sensitive information
+- Resume the conversation at a later time once the services are available again.
## Next steps
diff --git a/adev-ja/src/content/ai/overview.md b/adev-ja/src/content/ai/overview.md
index 253a70f753..a8ed4a1fe1 100644
--- a/adev-ja/src/content/ai/overview.md
+++ b/adev-ja/src/content/ai/overview.md
@@ -1,17 +1,18 @@
+
AI搭載アプリケーションを構築。AIで開発を加速。
-HELPFUL: お気に入りのAI統合IDEで開発を始めたい方は、[プロンプトルールとベストプラクティス](/ai/develop-with-ai)をご確認ください。
+HELPFUL: お気に入りのAI統合IDEで開発を始めたい方は、 [プロンプトルールとベストプラクティス](/ai/develop-with-ai)をご確認ください。
生成AI (GenAI)と大規模言語モデル (LLM)は、パーソナライズされたコンテンツ、インテリジェントなレコメンデーション、メディアの生成と理解、情報の要約、動的な機能など、高度で魅力的なアプリケーション体験の作成を可能にします。
このような機能の開発は、これまで深いドメイン知識と多大なエンジニアリング作業を必要としました。しかし、新しい製品とSDKが参入障壁を下げています。Angularは、以下の理由により、AIをウェブアプリケーションに統合するのに非常に適しています。
-* Angularの堅牢なテンプレートAPIにより、生成されたコンテンツから動的で整然と構成されたUIを作成できます
-* データと状態を動的に管理するために設計された、強力なシグナルベースのアーキテクチャ
-* AngularはAI SDKとAPIにシームレスに統合
+- Angularの堅牢なテンプレートAPIにより、生成されたコンテンツから動的で整然と構成されたUIを作成できます
+- データと状態を動的に管理するために設計された、強力なシグナルベースのアーキテクチャ
+- AngularはAI SDKとAPIにシームレスに統合
このガイドでは、[Genkit](/ai#build-ai-powered-applications-with-genkit-and-angular)、[Firebase AI Logic](/ai#build-ai-powered-applications-with-firebase-ai-logic-and-angular)、および[Gemini API](/ai#build-ai-powered-applications-with-gemini-api-and-angular)を使用して、AngularアプリケーションにAIを組み込む方法を示します。このガイドは、AngularアプリケーションにAIを統合する方法を説明することで、AI搭載ウェブアプリケーション開発の旅を加速させるでしょう。また、このガイドでは、迅速に習得できるスターターキット、サンプルコード、一般的なワークフローのレシピなどのリソースも共有しています。
@@ -19,7 +20,8 @@ HELPFUL: お気に入りのAI統合IDEで開発を始めたい方は、[プロ
NOTE: このページではGoogle AI製品との統合と例を紹介していますが、Genkitのようなツールはモデル非依存であり、独自のモデルを選択できます。多くの場合、これらの例とコードサンプルは他のサードパーティソリューションにも適用できます。
-## はじめに
+## はじめに {#getting-started}
+
AI搭載アプリケーションの構築は、新しく急速に発展している分野です。どこから始め、どの技術を選択するかを決定するのは難しい場合があります。以下のセクションでは、選択できる3つのオプションを提供します。
1. *Genkit*は、フルスタックアプリケーション構築のために、[サポートされているモデルと統合APIを備えたインターフェース](https://genkit.dev)の選択肢を提供します。パーソナライズされたレコメンデーションなど、高度なバックエンドAIロジックを必要とするアプリケーションに最適です。
@@ -29,39 +31,50 @@ AI搭載アプリケーションの構築は、新しく急速に発展してい
1. *Gemini API*を使用すると、APIサーフェスを通じて直接公開されるメソッドと機能を使用するアプリケーションを構築でき、フルスタックアプリケーションに最適です。カスタム画像生成やディープデータ処理など、AIモデルを直接制御する必要があるアプリケーションに適しています。
### GenkitとAngularでAI搭載アプリケーションを構築する {#build-ai-powered-applications-with-genkit-and-angular}
+
[Genkit](https://genkit.dev)は、ウェブアプリケーションやモバイルアプリケーションにAI搭載機能を構築するのに役立つように設計されたオープンソースツールキットです。Google、OpenAI、Anthropic、OllamaなどからのAIモデルを統合するための統合インターフェースを提供するため、ニーズに最適なモデルを探索して選択できます。サーバーサイドソリューションであるため、Genkitと統合するには、ウェブアプリケーションにはNode.jsベースのサーバーなどのサポートされているサーバー環境が必要です。たとえば、Angular SSRを使用してフルスタックアプリケーションを構築すると、サーバーサイドの開始コードが得られます。
GenkitとAngularで構築する方法の例を次に示します。
-* [GenkitとAngularのスターターキットを使用したエージェントアプリ](https://github.com/angular/examples/tree/main/genkit-angular-starter-kit)— AIでの構築は初めてですか?エージェントワークフローを備えた基本的なアプリケーションから始めましょう。初めてのAI構築体験に最適な場所です。
+- [GenkitとAngularのスターターキットを使用したエージェントアプリ](https://github.com/angular/examples/tree/main/genkit-angular-starter-kit)— AIでの構築は初めてですか?エージェントワークフローを備えた基本的なアプリケーションから始めましょう。初めてのAI構築体験に最適な場所です。
-* [AngularアプリでGenkitを使用する](https://genkit.dev/docs/angular/)— Genkit Flows、Angular、Gemini 2.5 Flashを使用する基本的なアプリケーションを構築します。このステップバイステップのウォークスルーは、AI機能を備えたフルスタックAngularアプリケーションの作成をガイドします。
+- [AngularアプリでGenkitを使用する](https://genkit.dev/docs/angular/)— Genkit Flows、Angular、Gemini 2.5 Flashを使用する基本的なアプリケーションを構築します。このステップバイステップのウォークスルーは、AI機能を備えたフルスタックAngularアプリケーションの作成をガイドします。
-* [動的ストーリー生成アプリ](https://github.com/angular/examples/tree/main/genkit-angular-story-generator)— Genkit、Gemini、Imagen 3を搭載したエージェントAngularアプリケーションを構築し、ユーザーインタラクションに基づいてストーリーを動的に生成し、発生するイベントに付随する美しい画像パネルを特徴とする方法を学びます。より高度なユースケースを試したい場合は、ここから始めましょう。
+- [動的ストーリー生成アプリ](https://github.com/angular/examples/tree/main/genkit-angular-story-generator)— Genkit、Gemini、Imagen 3を搭載したエージェントAngularアプリケーションを構築し、ユーザーインタラクションに基づいてストーリーを動的に生成し、発生するイベントに付随する美しい画像パネルを特徴とする方法を学びます。より高度なユースケースを試したい場合は、ここから始めましょう。
この例には、機能の詳細なビデオウォークスルーも含まれています。
- * [「AngularとGenkitでエージェントアプリを構築するライブ!」を見る](https://youtube.com/live/mx7yZoIa2n4?feature=share)
- * [「AngularとGenkitでエージェントアプリを構築するライブ!パート2」を見る](https://youtube.com/live/YR6LN5_o3B0?feature=share)
+ - [「AngularとGenkitでエージェントアプリを構築するライブ!」を見る](https://youtube.com/live/mx7yZoIa2n4?feature=share)
+ - [「AngularとGenkitでエージェントアプリを構築するライブ!パート2」を見る](https://youtube.com/live/YR6LN5_o3B0?feature=share)
+
+- [FirebaseとGoogle Cloudでエージェントアプリを構築する(バリスタの例)](https://developers.google.com/solutions/learn/agentic-barista) - FirebaseとGoogle Cloudでエージェントコーヒー注文アプリケーションを構築する方法を学びます。この例では、Firebase AI LogicとGenkitを使用しています。
-* [FirebaseとGoogle Cloudでエージェントアプリを構築する(バリスタの例)](https://developers.google.com/solutions/learn/agentic-barista) - FirebaseとGoogle Cloudでエージェントコーヒー注文アプリケーションを構築する方法を学びます。この例では、Firebase AI LogicとGenkitを使用しています。
+- [動的でサーバー駆動のUIの作成](https://github.com/angular/examples/tree/main/dynamic-sdui-app) - ユーザー入力に基づいて実行時に生成されるUIビューを持つエージェントAngularアプリケーションを構築する方法を学びます。
+
+ この例には、機能の詳細なビデオウォークスルーも含まれています。
+ - [「ウェブアプリケーションの未来を探る」を見る](https://www.youtube.com/live/4qargCqOu70?feature=share)
### Firebase AI LogicとAngularでAI搭載アプリケーションを構築する {#build-ai-powered-applications-with-firebase-ai-logic-and-angular}
+
[Firebase AI Logic](https://firebase.google.com/products/vertex-ai-in-firebase)は、Vertex AI Gemini APIやImagen APIとウェブアプリケーションやモバイルアプリケーションから直接安全にやり取りする方法を提供します。これは、アプリケーションがフルスタックまたはクライアントサイド専用のいずれかであるため、Angular開発者にとって魅力的です。クライアントサイド専用アプリケーションを開発している場合、Firebase AI LogicはウェブアプリケーションにAIを組み込むのに適しています。
Firebase AI LogicとAngularで構築する方法の例を次に示します。
-* [Firebase AI Logic x Angularスターターキット](https://github.com/angular/examples/tree/main/vertex-ai-firebase-angular-example) - このスターターキットを使用して、タスクを実行できるチャットエージェントを備えたeコマースアプリケーションを構築します。Firebase AI LogicとAngularでの構築経験がない場合は、ここから始めましょう。
+
+- [Firebase AI Logic x Angularスターターキット](https://github.com/angular/examples/tree/main/vertex-ai-firebase-angular-example) - このスターターキットを使用して、タスクを実行できるチャットエージェントを備えたeコマースアプリケーションを構築します。Firebase AI LogicとAngularでの構築経験がない場合は、ここから始めましょう。
この例には、[機能の説明と新機能の追加方法を示す詳細なビデオウォークスルー](https://youtube.com/live/4vfDz2al_BI)が含まれています。
### Gemini APIとAngularでAI搭載アプリケーションを構築する {#build-ai-powered-applications-with-gemini-api-and-angular}
+
[Gemini API](https://ai.google.dev/gemini-api/docs)は、音声、画像、動画、テキスト入力をサポートするGoogleの最先端モデルへのアクセスを提供します。特定のユースケースに最適化されたこれらのモデルについては、[Gemini APIドキュメントサイトで詳細を確認してください](https://ai.google.dev/gemini-api/docs/models)。
-* [AIテキストエディターAngularアプリテンプレート](https://github.com/FirebaseExtended/firebase-framework-tools/tree/main/starters/angular/ai-text-editor) - このテンプレートを使用して、テキストの洗練、テキストの拡張、テキストの形式化などのAI搭載機能を備えた完全に機能するテキストエディターから始めましょう。これは、HTTP経由でのGemini API呼び出しの経験を積むのに良い出発点です。
+- [AIテキストエディターAngularアプリテンプレート](https://github.com/FirebaseExtended/firebase-framework-tools/tree/main/starters/angular/ai-text-editor) - このテンプレートを使用して、テキストの洗練、テキストの拡張、テキストの形式化などのAI搭載機能を備えた完全に機能するテキストエディターから始めましょう。これは、HTTP経由でのGemini API呼び出しの経験を積むのに良い出発点です。
+
+- [AIチャットボットアプリテンプレート](https://github.com/FirebaseExtended/firebase-framework-tools/tree/main/starters/angular/ai-chatbot) - このテンプレートは、HTTP経由でGemini APIと通信するチャットボットユーザーインターフェースから始まります。
-* [AIチャットボットアプリテンプレート](https://github.com/FirebaseExtended/firebase-framework-tools/tree/main/starters/angular/ai-chatbot) - このテンプレートは、HTTP経由でGemini APIと通信するチャットボットユーザーインターフェースから始まります。
+## ベストプラクティス {#best-practices}
-## ベストプラクティス
### モデルプロバイダーへの接続とAPI認証情報の保護 {#connecting-to-model-providers-and-keeping-your-api-credentials-secure}
+
モデルプロバイダーに接続する際は、APIシークレットを安全に保つことが重要です。*APIキーを`environments.ts`のようなクライアントに配布されるファイルに決して含めないでください*。
アプリケーションのアーキテクチャによって、選択するAI APIとツールが決まります。具体的には、アプリケーションがクライアントサイドかサーバーサイドかに基づいて選択します。Firebase AI Logicのようなツールは、クライアントサイドのコードに対してモデルAPIへの安全な接続を提供します。Firebase AI Logic以外のAPIを使用したい場合や、別のモデルプロバイダーを使用したい場合は、プロキシサーバー、あるいは[Cloud Functions for Firebase](https://firebase.google.com/docs/functions)をプロキシとして使用し、APIキーを公開しないことを検討してください。
@@ -73,6 +86,7 @@ APIキーを必要とするモデルAPIへのサーバーサイド接続には
フルスタックアプリケーションにおけるサーバーサイド接続の例については、コード: [Angular AI Example (Genkit and Angular Story Generator) repository](https://github.com/angular/examples/tree/main/genkit-angular-story-generator)を参照してください。
### ツール呼び出しを使用してアプリケーションを強化する {#use-tool-calling-to-enhance-apps}
+
エージェントがプロンプトに基づいて問題を解決するために行動し、ツールを使用できるエージェントワークフローを構築したい場合は、「ツール呼び出し」を使用してください。ツール呼び出し(関数呼び出しとも呼ばれる)は、LLMにそれを呼び出したアプリケーションへリクエストを返す機能を提供する方法です。開発者として、どのツールが利用可能かを定義し、ツールがどのように、いつ呼び出されるかを制御します。
ツール呼び出しは、AI統合を質疑応答の形式のチャットボットよりもさらに拡張することで、ウェブアプリケーションをさらに強化します。実際、モデルプロバイダーの関数呼び出しAPIを使用して、モデルに関数呼び出しをリクエストさせることができます。利用可能なツールは、アプリケーションのコンテキスト内でより複雑なアクションを実行するために使用できます。
@@ -80,19 +94,22 @@ APIキーを必要とするモデルAPIへのサーバーサイド接続には
[Angular examples repository](https://github.com/angular/examples)の[eコマースの例](https://github.com/angular/examples/blob/main/vertex-ai-firebase-angular-example/src/app/ai.service.ts#L88)では、LLMは、店舗内の商品のグループがいくらになるかを計算するなどのより複雑なタスクを実行するために必要なコンテキストを得るために、在庫に関する関数呼び出しをリクエストします。利用可能なAPIの範囲は、LLMによってリクエストされた関数を呼び出すかどうかも含め、開発者であるあなた次第です。実行フローの制御はあなたが保持します。例えば、サービスの一部の関数は公開できますが、そのサービスのすべての関数を公開する必要はありません。
### 非決定論的な応答の処理 {#handling-non-deterministic-responses}
+
モデルは非決定論的な結果を返す可能性があるため、アプリケーションはその点を考慮して設計する必要があります。アプリケーションの実装で利用できるいくつかの戦略を以下に示します。
-* より決定論的な、またはより非決定論的な応答のために、プロンプトとモデルパラメーター([温度](https://ai.google.dev/gemini-api/docs/prompting-strategies)など)を調整します。[ai.google.dev](https://ai.google.dev/)の[プロンプト戦略セクション](https://ai.google.dev/gemini-api/docs/prompting-strategies)で詳細を確認できます。
-* ワークフローを進める前に人間が出力を検証する「ヒューマン・イン・ザ・ループ」戦略を使用します。オペレーター(人間または他のモデル)が出力を検証し、重要な決定を確認できるようにアプリケーションワークフローを構築します。
-* ツール(または関数)呼び出しとスキーマ制約を利用して、モデルの応答を事前定義された形式に誘導および制限し、応答の予測可能性を高めます。
+
+- より決定論的な、またはより非決定論的な応答のために、プロンプトとモデルパラメーター([温度](https://ai.google.dev/gemini-api/docs/prompting-strategies)など)を調整します。[ai.google.dev](https://ai.google.dev/)の[プロンプト戦略セクション](https://ai.google.dev/gemini-api/docs/prompting-strategies)で詳細を確認できます。
+- ワークフローを進める前に人間が出力を検証する「ヒューマン・イン・ザ・ループ」戦略を使用します。オペレーター(人間または他のモデル)が出力を検証し、重要な決定を確認できるようにアプリケーションワークフローを構築します。
+- ツール(または関数)呼び出しとスキーマ制約を利用して、モデルの応答を事前定義された形式に誘導および制限し、応答の予測可能性を高めます。
これらの戦略や技術を考慮しても、アプリケーション設計には適切なフォールバックを組み込む必要があります。アプリケーションの回復性に関する既存の標準に従ってください。例えば、リソースやAPIが利用できない場合にアプリケーションがクラッシュすることは許容されません。そのシナリオでは、エラーメッセージがユーザーに表示され、該当する場合は次のステップのオプションも表示されます。AIを活用したアプリケーションを構築する場合も、同様の考慮が必要です。応答が期待される出力と一致していることを確認し、一致しない場合は[グレースフルデグラデーション](https://developer.mozilla.org/en-US/docs/Glossary/Graceful_degradation)によって「安全な着地」を提供します。これは、LLMプロバイダーのAPI停止にも適用されます。
この例を考えてみましょう: LLMプロバイダーが応答していません。停止を処理するための潜在的な戦略は次のとおりです。
-* ユーザーからの応答を、再試行シナリオ(今すぐまたは後で)で使用するために保存します。
-* 機密情報を開示しない適切なメッセージで、ユーザーに停止を警告します。
-* サービスが再度利用できるようになったら、後で会話を再開します。
-## 次のステップ
+- ユーザーからの応答を、再試行シナリオ(今すぐまたは後で)で使用するために保存します。
+- 機密情報を開示しない適切なメッセージで、ユーザーに停止を警告します。
+- サービスが再度利用できるようになったら、後で会話を再開します。
+
+## 次のステップ {#next-steps}
LLMプロンプトとAI IDE設定について学ぶには、以下のガイドをご覧ください。
diff --git a/adev-ja/src/content/best-practices/a11y.en.md b/adev-ja/src/content/best-practices/a11y.en.md
index 7df1b3b399..bb51ce5c35 100644
--- a/adev-ja/src/content/best-practices/a11y.en.md
+++ b/adev-ja/src/content/best-practices/a11y.en.md
@@ -11,28 +11,48 @@ This page discusses best practices for designing Angular applications that work
## Accessibility attributes
-Building accessible web experience often involves setting [Accessible Rich Internet Applications \(ARIA\) attributes](https://web.dev/learn/accessibility/aria-html/) to provide semantic meaning where it might otherwise be missing.
+
+Building accessible web experiences often involves setting [Accessible Rich Internet Applications \(ARIA\) attributes](https://web.dev/learn/accessibility/aria-html/) to provide semantic meaning where it might otherwise be missing.
Use attribute binding template syntax to control the values of accessibility-related attributes.
-When binding to ARIA attributes in Angular, you must use the `attr.` prefix. The ARIA specification depends specifically on HTML attributes rather than properties of DOM elements.
+### ARIA attributes and properties
+
+When binding to ARIA attributes in Angular, you can use them directly like any other HTML attribute.
-
-…
+…
-NOTE: This syntax is only necessary for attribute *bindings*.
-Static ARIA attributes require no extra syntax.
+Static ARIA attributes work as regular HTML attributes.
-
…
HELPFUL: By convention, HTML attributes use lowercase names \(`tabindex`\), while properties use camelCase names \(`tabIndex`\).
-
-See the [Binding syntax guide](guide/templates) for more background on the difference between attributes and properties.
+Some ARIA patterns expose DOM APIs or directive inputs that accept structured values (for example, collections of `Element` references). Use standard property bindings for those cases so the underlying relationship stays synchronized.
+
+```angular-ts
+@Component({
+ template: `
+
Attention
+
Please review your answers before continuing.
+
+
+
+
+
+`,
+})
+export class ReviewDialog {}
+```
+
+Here `[ariaLabelledByElements]` accepts an array of elements, so property binding keeps the element references up to date whenever the template data changes.
+
+See the [binding guide](guide/templates/binding#aria-attributes) for a summary of ARIA attribute syntax.
## Angular UI components
@@ -40,11 +60,11 @@ The [Angular Material](https://material.angular.dev) library, which is maintaine
The [Component Development Kit (CDK)](https://material.angular.dev/cdk/categories) includes the `a11y` package that provides tools to support various areas of accessibility.
For example:
-* `LiveAnnouncer` is used to announce messages for screen-reader users using an `aria-live` region.
- See the W3C documentation for more information on [aria-live regions](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live).
+- `LiveAnnouncer` is used to announce messages for screen-reader users using an `aria-live` region.
+ See the W3C documentation for more information on [aria-live regions](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live).
-* The `cdkTrapFocus` directive traps Tab-key focus within an element.
- Use it to create accessible experience for components such as modal dialogs, where focus must be constrained.
+- The `cdkTrapFocus` directive traps Tab-key focus within an element.
+ Use it to create accessible experience for components such as modal dialogs, where focus must be constrained.
For full details of these and other tools, see the [Angular CDK accessibility overview](https://material.angular.dev/cdk/a11y/overview).
@@ -63,7 +83,7 @@ You can see examples of this pattern in Angular Material:
Sometimes using the appropriate native element requires a container element.
For example, the native `` element cannot have children, so any custom text entry components need to wrap an `` with extra elements.
-By just including `` in your custom component's template, it's impossible for your component's users to set arbitrary properties and attributes to the `` element.
+By just including `` in your custom component's template, it's impossible for your component's users to set arbitrary properties and attributes to the `` element.
Instead, create a container component that uses content projection to include the native control in the component's API.
You can see [`MatFormField`](https://material.angular.dev/components/form-field/overview) as an example of this pattern.
@@ -72,9 +92,9 @@ You can see [`MatFormField`](https://material.angular.dev/components/form-field/
The following example shows how to make a progress bar accessible by using host binding to control accessibility-related attributes.
-* The component defines an accessibility-enabled element with both the standard HTML attribute `role`, and ARIA attributes.
- The ARIA attribute `aria-valuenow` is bound to the user's input.
-* In the template, the `aria-label` attribute ensures that the control is accessible to screen readers.
+- The component defines an accessibility-enabled element with both the standard HTML attribute `role`, and ARIA attributes.
+ The ARIA attribute `aria-valuenow` is bound to the user's input.
+- In the template, the `aria-label` attribute ensures that the control is accessible to screen readers.
-
-router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
- const mainHeader = document.querySelector('#main-content-header')
+```ts
+router.events.pipe(filter((e) => e instanceof NavigationEnd)).subscribe(() => {
+ const mainHeader = document.querySelector('#main-content-header');
if (mainHeader) {
mainHeader.focus();
}
});
-
-
+```
In a real application, the element that receives focus depends on your specific application structure and layout.
The focused element should put users in a position to immediately move into the main content that has just been routed into view.
@@ -149,17 +167,25 @@ The following example shows how to apply the `active-page` class to active links
+## Deferred Loading
+
+When using Angular's `@defer` blocks for lazy loading content, consider the accessibility implications for users with assistive technologies.
+Screen readers may not automatically announce content changes when deferred components load, potentially leaving users unaware of new content.
+
+To ensure deferred content changes are properly announced, wrap your `@defer` blocks in elements with appropriate ARIA live regions.
+For detailed guidance and examples, see the [accessibility section in the defer guide](/guide/templates/defer#keep-accessibility-in-mind).
+
## More information
-* [Accessibility - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility)
-* [ARIA specification and authoring practices](https://www.w3.org/TR/wai-aria)
-* [Material Design - Accessibility](https://material.io/design/usability/accessibility.html)
-* [Smashing Magazine](https://www.smashingmagazine.com/search/?q=accessibility)
-* [Inclusive Components](https://inclusive-components.design)
-* [Accessibility Resources and Code Examples](https://dequeuniversity.com/resources)
-* [W3C - Web Accessibility Initiative](https://www.w3.org/WAI/people-use-web)
-* [Rob Dodson A11ycasts](https://www.youtube.com/watch?v=HtTyRajRuyY)
-* [Angular ESLint](https://github.com/angular-eslint/angular-eslint#functionality) provides linting rules that can help you make sure your code meets accessibility standards.
+- [Accessibility - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility)
+- [ARIA specification and authoring practices](https://www.w3.org/TR/wai-aria)
+- [Material Design - Accessibility](https://material.io/design/usability/accessibility.html)
+- [Smashing Magazine](https://www.smashingmagazine.com/search/?q=accessibility)
+- [Inclusive Components](https://inclusive-components.design)
+- [Accessibility Resources and Code Examples](https://dequeuniversity.com/resources)
+- [W3C - Web Accessibility Initiative](https://www.w3.org/WAI/people-use-web)
+- [Rob Dodson A11ycasts](https://www.youtube.com/watch?v=HtTyRajRuyY)
+- [Angular ESLint](https://github.com/angular-eslint/angular-eslint#functionality) provides linting rules that can help you make sure your code meets accessibility standards.
@@ -167,7 +193,7 @@ Books
-* "A Web for Everyone: Designing Accessible User Experiences," Sarah Horton and Whitney Quesenbery
-* "Inclusive Design Patterns," Heydon Pickering
+- "A Web for Everyone: Designing Accessible User Experiences," Sarah Horton and Whitney Quesenbery
+- "Inclusive Design Patterns," Heydon Pickering
diff --git a/adev-ja/src/content/best-practices/a11y.md b/adev-ja/src/content/best-practices/a11y.md
index 0cf7da9b3d..b7a8a8ced6 100644
--- a/adev-ja/src/content/best-practices/a11y.md
+++ b/adev-ja/src/content/best-practices/a11y.md
@@ -8,47 +8,67 @@
このページでは、支援技術に依存する人々を含むすべてのユーザーにとって適切に機能するAngularアプリケーションを設計するためのベストプラクティスについて説明します。
-## アクセシビリティ属性
+## アクセシビリティ属性 {#accessibility-attributes}
+
アクセシブルなウェブエクスペリエンスを構築することは、多くの場合、[Accessible Rich Internet Applications (ARIA)属性](https://web.dev/learn/accessibility/aria-html/)を設定して、そうでなければ欠落しているセマンティックな意味を提供することを伴います。
属性バインディングテンプレート構文を使用して、アクセシビリティ関連属性の値を制御します。
-AngularでARIA属性にバインドする場合、`attr.`プレフィックスを使用する必要があります。ARIA仕様は、DOM要素のプロパティではなく、特にHTML属性に依存します。
+### ARIA属性とプロパティ {#aria-attributes-and-properties}
+
+AngularでARIA属性にバインドする場合、他のHTML属性と同様に直接使用できます。
-
-…
+…
-NOTE: この構文は、属性*バインディング*の場合にのみ必要です。
-静的ARIA属性には、追加の構文は必要ありません。
+静的ARIA属性は通常のHTML属性として機能します。
-
…
HELPFUL: 慣習的に、HTML属性は小文字の名前を使用します (`tabindex`)、一方プロパティはcamelCaseの名前を使用します (`tabIndex`)。
-
-属性とプロパティの違いの詳細については、[バインディング構文ガイド](guide/templates)を参照してください。
+一部のARIAパターンは、構造化された値(例: `Element` 参照のコレクション)を受け入れるDOM APIまたはディレクティブ入力を公開します。そのような場合は、標準のプロパティバインディングを使用して、基礎となる関係を同期させます。
+
+```angular-ts
+@Component({
+ template: `
+
Attention
+
Please review your answers before continuing.
+
+
+
+
+
+`,
+})
+export class ReviewDialog {}
+```
+
+ここで `[ariaLabelledByElements]` は要素の配列を受け入れるため、プロパティバインディングは、テンプレートデータが変更されるたびに要素参照を最新の状態に保ちます。
+
+ARIA属性構文の概要については、[バインディングガイド](guide/templates/binding#aria-attributes)を参照してください。
-## Angular UIコンポーネント
+## Angular UIコンポーネント {#angular-ui-components}
Angularチームが保守している[Angular Material](https://material.angular.dev)ライブラリは、完全なアクセシビリティを目指した、再利用可能なUIコンポーネントのスイートです。
[Component Development Kit (CDK)](https://material.angular.dev/cdk/categories)には、アクセシビリティのさまざまな領域をサポートするためのツールを提供する`a11y`パッケージが含まれています。
例えば:
-* `LiveAnnouncer`は、`aria-live`領域を使用して、スクリーンリーダーユーザーにメッセージを発表するために使用されます。
- [aria-live領域](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live)の詳細については、W3Cのドキュメントを参照してください。
+- `LiveAnnouncer`は、`aria-live`領域を使用して、スクリーンリーダーユーザーにメッセージを発表するために使用されます。
+ [aria-live領域](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live)の詳細については、W3Cのドキュメントを参照してください。
-* `cdkTrapFocus`ディレクティブは、Tabキーのフォーカスを要素内に閉じ込めておきます。
- モーダルダイアログなど、フォーカスを制限する必要があるコンポーネントのアクセシブルなエクスペリエンスを作成するために使用します。
+- `cdkTrapFocus`ディレクティブは、Tabキーのフォーカスを要素内に閉じ込めておきます。
+ モーダルダイアログなど、フォーカスを制限する必要があるコンポーネントのアクセシブルなエクスペリエンスを作成するために使用します。
これらのツールやその他のツールの詳細については、[Angular CDKアクセシビリティの概要](https://material.angular.dev/cdk/a11y/overview)を参照してください。
-### ネイティブ要素の拡張
+### ネイティブ要素の拡張 {#augmenting-native-elements}
ネイティブHTML要素は、アクセシビリティにとって重要な、いくつかの標準的な相互作用パターンを捉えています。
Angularコンポーネントを作成する際には、サポートされている動作を再実装するのではなく、可能な限りこれらのネイティブ要素を直接再利用する必要があります。
@@ -59,7 +79,7 @@ Angularコンポーネントを作成する際には、サポートされてい
このパターンの例は、Angular Materialで見ることができます:
[`MatButton`](https://github.com/angular/components/blob/main/src/material/button/button.ts#L33C3-L36C5)、[`MatTabNav`](https://github.com/angular/components/blob/main/src/material/tabs/tab-nav-bar/tab-nav-bar.ts#L62)、および[`MatTable`](https://github.com/angular/components/blob/main/src/material/table/table.ts#L40)。
-### ネイティブ要素のためのコンテナの使用
+### ネイティブ要素のためのコンテナの使用 {#using-containers-for-native-elements}
ネイティブ要素を使用するには、コンテナ要素が必要になる場合があります。
たとえば、ネイティブの``要素は子を持たせることができないため、カスタムテキスト入力コンポーネントは``を余分な要素でラップする必要があります。
@@ -68,13 +88,13 @@ Angularコンポーネントを作成する際には、サポートされてい
[`MatFormField`](https://material.angular.dev/components/form-field/overview)は、このパターンの例として見ることができます。
-## ケーススタディ: カスタムプログレスバーの構築
+## ケーススタディ: カスタムプログレスバーの構築 {#case-study-building-a-custom-progress-bar}
次の例は、ホストバインディングを使用してアクセシビリティ関連属性を制御することで、プログレスバーをアクセシブルにする方法を示しています。
-* コンポーネントは、標準のHTML属性`role`とARIA属性の両方を持つ、アクセシビリティ対応の要素を定義します。
- ARIA属性`aria-valuenow`は、ユーザーの入力にバインドされます。
-* テンプレートでは、`aria-label`属性により、コントロールはスクリーンリーダーにとってアクセシブルになります。
+- コンポーネントは、標準のHTML属性`role`とARIA属性の両方を持つ、アクセシビリティ対応の要素を定義します。
+ ARIA属性`aria-valuenow`は、ユーザーの入力にバインドされます。
+- テンプレートでは、`aria-label`属性により、コントロールはスクリーンリーダーにとってアクセシブルになります。
-## ルーティング
+## ルーティング {#routing}
-### ナビゲーション後のフォーカス管理
+### ナビゲーション後のフォーカス管理 {#focus-management-after-navigation}
UIにおける[フォーカス](https://web.dev/learn/accessibility/focus/)の追跡と制御は、アクセシビリティを考慮する上で重要な要素です。
Angularルーティングを使用する場合は、ページナビゲーション時にページフォーカスがどこに移動するかを決定する必要があります。
@@ -101,22 +121,20 @@ Angularルーティングを使用する場合は、ページナビゲーショ
次の例は、ナビゲーション後にDOM内のメインコンテンツヘッダーを見つけてフォーカスする方法を示しています。
-
-
-router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
- const mainHeader = document.querySelector('#main-content-header')
+```ts
+router.events.pipe(filter((e) => e instanceof NavigationEnd)).subscribe(() => {
+ const mainHeader = document.querySelector('#main-content-header');
if (mainHeader) {
mainHeader.focus();
}
});
-
-
+```
実際のアプリケーションでは、フォーカスを受け取る要素は、特定のアプリケーションの構造とレイアウトによって異なります。
フォーカスされる要素は、ユーザーを、ちょうどビューにルーティングされたメインコンテンツにすぐに移動できる位置に置く必要があります。
ルート変更後にフォーカスが`body`要素に戻るような状況は避ける必要があります。
-### アクティブリンクの識別
+### アクティブリンクの識別 {#active-links-identification}
`RouterLinkActive`など、アクティブな`RouterLink`要素に適用されるCSSクラスは、アクティブなリンクを視覚的に識別するための手がかりを提供します。
残念ながら、視覚的な手がかりは、盲人または視覚障害のあるユーザーには役立ちません。
@@ -149,17 +167,25 @@ router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
-## 詳細情報
+## 遅延読み込み {#deferred-loading}
+
+Angularの`@defer`ブロックを使用してコンテンツを遅延読み込みする場合、支援技術を使用するユーザーへのアクセシビリティの影響を考慮してください。
+スクリーンリーダーは、遅延コンポーネントが読み込まれたときにコンテンツの変更を自動的に通知しない場合があり、ユーザーが新しいコンテンツに気づかない可能性があります。
+
+遅延コンテンツの変更が適切に通知されるようにするには、適切なARIAライブ領域を持つ要素で`@defer`ブロックをラップします。
+詳細なガイダンスと例については、[deferガイドのアクセシビリティセクション](/guide/templates/defer#keep-accessibility-in-mind)を参照してください。
+
+## 詳細情報 {#more-information}
-* [アクセシビリティ - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility)
-* [ARIA仕様とオーサリングプラクティス](https://www.w3.org/TR/wai-aria)
-* [マテリアルデザイン - アクセシビリティ](https://material.io/design/usability/accessibility.html)
-* [Smashing Magazine](https://www.smashingmagazine.com/search/?q=accessibility)
-* [Inclusive Components](https://inclusive-components.design)
-* [アクセシビリティリソースとコード例](https://dequeuniversity.com/resources)
-* [W3C - ウェブアクセシビリティイニシアチブ](https://www.w3.org/WAI/people-use-web)
-* [Rob Dodson A11ycasts](https://www.youtube.com/watch?v=HtTyRajRuyY)
-* [Angular ESLint](https://github.com/angular-eslint/angular-eslint#functionality)は、コードがアクセシビリティ基準を満たしていることを確認するのに役立つ、リンティングルールを提供します。
+- [アクセシビリティ - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility)
+- [ARIA仕様とオーサリングプラクティス](https://www.w3.org/TR/wai-aria)
+- [マテリアルデザイン - アクセシビリティ](https://material.io/design/usability/accessibility.html)
+- [Smashing Magazine](https://www.smashingmagazine.com/search/?q=accessibility)
+- [Inclusive Components](https://inclusive-components.design)
+- [アクセシビリティリソースとコード例](https://dequeuniversity.com/resources)
+- [W3C - ウェブアクセシビリティイニシアチブ](https://www.w3.org/WAI/people-use-web)
+- [Rob Dodson A11ycasts](https://www.youtube.com/watch?v=HtTyRajRuyY)
+- [Angular ESLint](https://github.com/angular-eslint/angular-eslint#functionality)は、コードがアクセシビリティ基準を満たしていることを確認するのに役立つ、リンティングルールを提供します。
@@ -167,7 +193,7 @@ router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
-* "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
-* "Inclusive Design Patterns", Heydon Pickering
+- "A Web for Everyone: Designing Accessible User Experiences," Sarah Horton and Whitney Quesenbery
+- "Inclusive Design Patterns," Heydon Pickering
diff --git a/adev-ja/src/content/best-practices/error-handling.md b/adev-ja/src/content/best-practices/error-handling.md
index 36dbb05177..c4cd17a7f6 100644
--- a/adev-ja/src/content/best-practices/error-handling.md
+++ b/adev-ja/src/content/best-practices/error-handling.md
@@ -8,7 +8,7 @@ For example, consider a component that fetches user data from an API. The code r
## Unhandled errors are reported to the `ErrorHandler`
-Angular reports unhandled errors to the application's root [ErrorHandler](api/core/ErrorHandler). When providing a custom `ErrorHandler`, provide it in your `ApplicationConfig` as part of calling `bootstrapApplication`.
+Angular reports unhandled errors to the application's root `ErrorHandler`. When providing a custom `ErrorHandler`, provide it in your `ApplicationConfig` as part of calling `bootstrapApplication`.
When building an Angular application, often you write code that is called automatically _by_ the framework. For example, Angular is responsible for calling a component's constructor and lifecycle methods when that component appears in a template. When the framework runs your code, there's nowhere you could reasonably add a `try` block to gracefully handle errors. In situations like this, Angular catches errors and sends them to the `ErrorHandler`.
@@ -16,13 +16,33 @@ Angular does _not_ catch errors inside of APIs that are called directly by your
Angular catches _asynchronous_ errors from user promises or observables only when:
-* There is an explicit contract for Angular to wait for and use the result of the asynchronous operation, and
-* When errors are not presented in the return value or state.
+- There is an explicit contract for Angular to wait for and use the result of the asynchronous operation, and
+- When errors are not presented in the return value or state.
For example, `AsyncPipe` and `PendingTasks.run` forward errors to the `ErrorHandler`, whereas `resource` presents the error in the `status` and `error` properties.
Errors that Angular reports to the `ErrorHandler` are _unexpected_ errors. These errors may be unrecoverable or an indication that the state of the application is corrupted. Applications should provide error handling using `try` blocks or appropriate error handling operators (like `catchError` in RxJS) where the error occurs whenever possible rather than relying on the `ErrorHandler`, which is most frequently and appropriately used only as a mechanism to report potentially fatal errors to the error tracking and logging infrastructure.
+```ts
+export class GlobalErrorHandler implements ErrorHandler {
+ private readonly analyticsService = inject(AnalyticsService);
+ private readonly router = inject(Router);
+
+ handleError(error: any) {
+ const url = this.router.url;
+ const errorMessage = error?.message ?? 'unknown';
+
+ this.analyticsService.trackEvent({
+ eventName: 'exception',
+ description: `Screen: ${url} | ${errorMessage}`,
+ });
+
+ console.error(GlobalErrorHandler.name, { error });
+ }
+}
+
+```
+
### `TestBed` rethrows errors by default
In many cases, `ErrorHandler` may only log errors and otherwise allow the application to continue running. In tests, however, you almost always want to surface these errors. Angular's `TestBed` rethrows unexpected errors to ensure that errors caught by the framework cannot be unintentionally missed or ignored. In rare circumstances, a test may specifically attempt to ensure errors do not cause the application to be unresponsive or crash. In these situations, you can [configure `TestBed` to _not_ rethrow application errors](api/core/testing/TestModuleMetadata#rethrowApplicationErrors) with `TestBed.configureTestingModule({rethrowApplicationErrors: false})`.
diff --git a/adev-ja/src/content/best-practices/runtime-performance/skipping-subtrees.en.md b/adev-ja/src/content/best-practices/runtime-performance/skipping-subtrees.en.md
index 64e984dddf..39313fb006 100644
--- a/adev-ja/src/content/best-practices/runtime-performance/skipping-subtrees.en.md
+++ b/adev-ja/src/content/best-practices/runtime-performance/skipping-subtrees.en.md
@@ -10,8 +10,8 @@ If you are confident that a part of the application is not affected by a state c
OnPush change detection instructs Angular to run change detection for a component subtree **only** when:
-* The root component of the subtree receives new inputs as the result of a template binding. Angular compares the current and past value of the input with `==`.
-* Angular handles an event _(for example using event binding, output binding, or `@HostListener` )_ in the subtree's root component or any of its children whether they are using OnPush change detection or not.
+- The root component of the subtree receives new inputs as the result of a template binding. Angular compares the current and past value of the input with `==`.
+- Angular handles an event _(for example using event binding, output binding, or `@HostListener` )_ in the subtree's root component or any of its children whether they are using OnPush change detection or not.
You can set the change detection strategy of a component to `OnPush` in the `@Component` decorator:
@@ -128,5 +128,5 @@ class event eventNode
## Edge cases
-* **Modifying input properties in TypeScript code**. When you use an API like `@ViewChild` or `@ContentChild` to get a reference to a component in TypeScript and manually modify an `@Input` property, Angular will not automatically run change detection for OnPush components. If you need Angular to run change detection, you can inject `ChangeDetectorRef` in your component and call `changeDetectorRef.markForCheck()` to tell Angular to schedule a change detection.
-* **Modifying object references**. In case an input receives a mutable object as value and you modify the object but preserve the reference, Angular will not invoke change detection. That’s the expected behavior because the previous and the current value of the input point to the same reference.
+- **Modifying input properties in TypeScript code**. When you use an API like `@ViewChild` or `@ContentChild` to get a reference to a component in TypeScript and manually modify an `@Input` property, Angular will not automatically run change detection for OnPush components. If you need Angular to run change detection, you can inject `ChangeDetectorRef` in your component and call `changeDetectorRef.markForCheck()` to tell Angular to schedule a change detection.
+- **Modifying object references**. In case an input receives a mutable object as value and you modify the object but preserve the reference, Angular will not invoke change detection. That’s the expected behavior because the previous and the current value of the input point to the same reference.
diff --git a/adev-ja/src/content/best-practices/runtime-performance/skipping-subtrees.md b/adev-ja/src/content/best-practices/runtime-performance/skipping-subtrees.md
index 7b306a15a0..326d6e2496 100644
--- a/adev-ja/src/content/best-practices/runtime-performance/skipping-subtrees.md
+++ b/adev-ja/src/content/best-practices/runtime-performance/skipping-subtrees.md
@@ -10,8 +10,8 @@ JavaScriptは、デフォルトでは、複数の異なるコンポーネント
OnPush変更検知は、Angularにコンポーネントのサブツリーの変更検知を次の場合**のみ**実行するように指示します。
-* サブツリーのルートコンポーネントが、テンプレートバインディングの結果として新しいインプットを受け取った場合。Angularは、インプットの現在と過去の値を`==`で比較します。
-* Angularが、OnPush変更検知を使用しているかどうかに関係なく、サブツリーのルートコンポーネント、または、その子でイベント *(例えば、イベントバインディング、アウトプットバインディング、または`@HostListener`を使用)* を処理する場合。
+- サブツリーのルートコンポーネントが、テンプレートバインディングの結果として新しいインプットを受け取った場合。Angularは、インプットの現在と過去の値を`==`で比較します。
+- Angularが、OnPush変更検知を使用しているかどうかに関係なく、サブツリーのルートコンポーネント、または、その子でイベント *(例えば、イベントバインディング、アウトプットバインディング、または`@HostListener`を使用)* を処理する場合。
コンポーネントの変更検知戦略を`@Component`デコレーターで`OnPush`に設定できます。
@@ -128,5 +128,5 @@ class event eventNode
## エッジケース
-* **TypeScriptコードでインプットプロパティを変更する**。`@ViewChild`や`@ContentChild`のようなAPIを使用して、TypeScriptでコンポーネントへの参照を取得し、`@Input`プロパティを手動で変更すると、AngularはOnPushコンポーネントの変更検知を自動的に実行しません。Angularに変更検知を実行させる必要がある場合は、コンポーネントに`ChangeDetectorRef`を注入し、`changeDetectorRef.markForCheck()`を呼び出して、Angularに変更検知をスケジュールするように指示できます。
-* **オブジェクト参照の変更**。インプットが可変オブジェクトを値として受け取り、オブジェクトを変更しても参照を保持する場合、Angularは変更検知を呼び出しません。これは、インプットの以前の値と現在の値が同じ参照を指していることによる想定通りの動作です。
+- **TypeScriptコードでインプットプロパティを変更する**。`@ViewChild`や`@ContentChild`のようなAPIを使用して、TypeScriptでコンポーネントへの参照を取得し、`@Input`プロパティを手動で変更すると、AngularはOnPushコンポーネントの変更検知を自動的に実行しません。Angularに変更検知を実行させる必要がある場合は、コンポーネントに`ChangeDetectorRef`を注入し、`changeDetectorRef.markForCheck()`を呼び出して、Angularに変更検知をスケジュールするように指示できます。
+- **オブジェクト参照の変更**。インプットが可変オブジェクトを値として受け取り、オブジェクトを変更しても参照を保持する場合、Angularは変更検知を呼び出しません。これは、インプットの以前の値と現在の値が同じ参照を指していることによる想定通りの動作です。
diff --git a/adev-ja/src/content/best-practices/runtime-performance/slow-computations.md b/adev-ja/src/content/best-practices/runtime-performance/slow-computations.md
index 38f8aabea6..744080ee3d 100644
--- a/adev-ja/src/content/best-practices/runtime-performance/slow-computations.md
+++ b/adev-ja/src/content/best-practices/runtime-performance/slow-computations.md
@@ -2,13 +2,13 @@
On every change detection cycle, Angular synchronously:
-* Evaluates all template expressions in all components, unless specified otherwise, based on that each component's detection strategy
-* Executes the `ngDoCheck`, `ngAfterContentChecked`, `ngAfterViewChecked`, and `ngOnChanges` lifecycle hooks.
-A single slow computation within a template or a lifecycle hook can slow down the entire change detection process because Angular runs the computations sequentially.
+- Evaluates all template expressions in all components, unless specified otherwise, based on that each component's detection strategy
+- Executes the `ngDoCheck`, `ngAfterContentChecked`, `ngAfterViewChecked`, and `ngOnChanges` lifecycle hooks.
+ A single slow computation within a template or a lifecycle hook can slow down the entire change detection process because Angular runs the computations sequentially.
## Identifying slow computations
-You can identify heavy computations with Angular DevTools’ profiler. In the performance timeline, click a bar to preview a particular change detection cycle. This displays a bar chart, which shows how long the framework spent in change detection for each component. When you click a component, you can preview how long Angular spent evaluating its template and lifecycle hooks.
+You can identify heavy computations with Angular DevTools’ profiler. In the performance timeline, click a bar to preview a particular change detection cycle. This displays a bar chart, which shows how long the framework spent in change detection for each component. When you click a component, you can preview how long Angular spent evaluating its template and lifecycle hooks.
@@ -18,9 +18,9 @@ For example, in the preceding screenshot, the second recorded change detection c
Here are several techniques to remove slow computations:
-* **Optimizing the underlying algorithm**. This is the recommended approach. If you can speed up the algorithm that is causing the problem, you can speed up the entire change detection mechanism.
-* **Caching using pure pipes**. You can move the heavy computation to a pure [pipe](guide/pipes). Angular reevaluates a pure pipe only if it detects that its inputs have changed, compared to the previous time Angular called it.
-* **Using memoization**. [Memoization](https://en.wikipedia.org/wiki/Memoization) is a similar technique to pure pipes, with the difference that pure pipes preserve only the last result from the computation where memoization could store multiple results.
-* **Avoid repaints/reflows in lifecycle hooks**. Certain [operations](https://web.dev/avoid-large-complex-layouts-and-layout-thrashing/) cause the browser to either synchronously recalculate the layout of the page or re-render it. Since reflows and repaints are generally slow, you want to avoid performing them in every change detection cycle.
+- **Optimizing the underlying algorithm**. This is the recommended approach. If you can speed up the algorithm that is causing the problem, you can speed up the entire change detection mechanism.
+- **Caching using pure pipes**. You can move the heavy computation to a pure [pipe](guide/pipes). Angular reevaluates a pure pipe only if it detects that its inputs have changed, compared to the previous time Angular called it.
+- **Using memoization**. [Memoization](https://en.wikipedia.org/wiki/Memoization) is a similar technique to pure pipes, with the difference that pure pipes preserve only the last result from the computation where memoization could store multiple results.
+- **Avoid repaints/reflows in lifecycle hooks**. Certain [operations](https://web.dev/avoid-large-complex-layouts-and-layout-thrashing/) cause the browser to either synchronously recalculate the layout of the page or re-render it. Since reflows and repaints are generally slow, you want to avoid performing them in every change detection cycle.
Pure pipes and memoization have different trade-offs. Pure pipes are an Angular built-in concept compared to memoization, which is a general software engineering practice for caching function results. The memory overhead of memoization could be significant if you invoke the heavy computation frequently with different arguments.
diff --git a/adev-ja/src/content/best-practices/runtime-performance/zone-pollution.md b/adev-ja/src/content/best-practices/runtime-performance/zone-pollution.md
index e232ec090b..37cdf73672 100644
--- a/adev-ja/src/content/best-practices/runtime-performance/zone-pollution.md
+++ b/adev-ja/src/content/best-practices/runtime-performance/zone-pollution.md
@@ -4,8 +4,8 @@
In some cases scheduled [tasks](https://developer.mozilla.org/docs/Web/API/HTML_DOM_API/Microtask_guide#tasks) or [microtasks](https://developer.mozilla.org/docs/Web/API/HTML_DOM_API/Microtask_guide#microtasks) don’t make any changes in the data model, which makes running change detection unnecessary. Common examples are:
-* `requestAnimationFrame`, `setTimeout` or `setInterval`
-* Task or microtask scheduling by third-party libraries
+- `requestAnimationFrame`, `setTimeout` or `setInterval`
+- Task or microtask scheduling by third-party libraries
This section covers how to identify such conditions, and how to run code outside the Angular zone to avoid unnecessary change detection calls.
@@ -26,11 +26,11 @@ import { Component, NgZone, OnInit } from '@angular/core';
@Component(...)
class AppComponent implements OnInit {
- private ngZone = inject(NgZone);
+private ngZone = inject(NgZone);
- ngOnInit() {
- this.ngZone.runOutsideAngular(() => setInterval(pollForUpdates), 500);
- }
+ngOnInit() {
+this.ngZone.runOutsideAngular(() => setInterval(pollForUpdates), 500);
+}
}
@@ -44,13 +44,13 @@ import * as Plotly from 'plotly.js-dist-min';
@Component(...)
class AppComponent implements OnInit {
- private ngZone = inject(NgZone);
+private ngZone = inject(NgZone);
- ngOnInit() {
- this.ngZone.runOutsideAngular(() => {
- Plotly.newPlot('chart', data);
- });
- }
+ngOnInit() {
+this.ngZone.runOutsideAngular(() => {
+Plotly.newPlot('chart', data);
+});
+}
}
@@ -66,18 +66,18 @@ import * as Plotly from 'plotly.js-dist-min';
@Component(...)
class AppComponent implements OnInit {
- private ngZone = inject(NgZone);
+private ngZone = inject(NgZone);
- plotlyClick = output();
+plotlyClick = output();
- ngOnInit() {
- this.ngZone.runOutsideAngular(() => {
- this.createPlotly();
- });
- }
+ngOnInit() {
+this.ngZone.runOutsideAngular(() => {
+this.createPlotly();
+});
+}
- private async createPlotly() {
- const plotly = await Plotly.newPlot('chart', data);
+private async createPlotly() {
+const plotly = await Plotly.newPlot('chart', data);
plotly.on('plotly_click', (event: Plotly.PlotMouseEvent) => {
// This handler will be called outside of the Angular zone because
@@ -86,7 +86,8 @@ class AppComponent implements OnInit {
console.log(NgZone.isInAngularZone());
this.plotlyClick.emit(event);
});
- }
+
+}
}
@@ -98,26 +99,27 @@ import * as Plotly from 'plotly.js-dist-min';
@Component(...)
class AppComponent implements OnInit {
- private ngZone = inject(NgZone);
+private ngZone = inject(NgZone);
- plotlyClick = output();
+plotlyClick = output();
- ngOnInit() {
- this.ngZone.runOutsideAngular(() => {
- this.createPlotly();
- });
- }
+ngOnInit() {
+this.ngZone.runOutsideAngular(() => {
+this.createPlotly();
+});
+}
- private async createPlotly() {
- const plotly = await Plotly.newPlot('chart', data);
+private async createPlotly() {
+const plotly = await Plotly.newPlot('chart', data);
plotly.on('plotly_click', (event: Plotly.PlotMouseEvent) => {
this.ngZone.run(() => {
this.plotlyClick.emit(event);
});
});
- }
+
+}
}
-The scenario of dispatching events outside of the Angular zone may also arise. It's important to remember that triggering change detection (for example, manually) may result in the creation/update of views outside of the Angular zone.
\ No newline at end of file
+The scenario of dispatching events outside of the Angular zone may also arise. It's important to remember that triggering change detection (for example, manually) may result in the creation/update of views outside of the Angular zone.
diff --git a/adev-ja/src/content/best-practices/style-guide.en.md b/adev-ja/src/content/best-practices/style-guide.en.md
index 63128d8535..11e02dedfd 100644
--- a/adev-ja/src/content/best-practices/style-guide.en.md
+++ b/adev-ja/src/content/best-practices/style-guide.en.md
@@ -112,10 +112,10 @@ When in doubt, go with the approach that leads to smaller files.
Prefer using the `inject` function over injecting constructor parameters. The `inject` function works the same way as constructor parameter injection, but offers several style advantages:
-* `inject` is generally more readable, especially when a class injects many dependencies.
-* It's more syntactically straightforward to add comments to injected dependencies
-* `inject` offers better type inference.
-* When targeting ES2022+ with [`useDefineForClassFields`](https://www.typescriptlang.org/tsconfig/#useDefineForClassFields), you can avoid separating field declaration and initialization when fields read on injected dependencies.
+- `inject` is generally more readable, especially when a class injects many dependencies.
+- It's more syntactically straightforward to add comments to injected dependencies
+- `inject` offers better type inference.
+- When targeting ES2022+ with [`useDefineForClassFields`](https://www.typescriptlang.org/tsconfig/#useDefineForClassFields), you can avoid separating field declaration and initialization when fields read on injected dependencies.
[You can refactor existing code to `inject` with an automatic tool](reference/migrations/inject-function).
diff --git a/adev-ja/src/content/best-practices/style-guide.md b/adev-ja/src/content/best-practices/style-guide.md
index ae71e9c141..9f28e8804d 100644
--- a/adev-ja/src/content/best-practices/style-guide.md
+++ b/adev-ja/src/content/best-practices/style-guide.md
@@ -112,10 +112,10 @@ src/
コンストラクターパラメーターインジェクションよりも`inject`関数を使用することを推奨します。`inject`関数はコンストラクターパラメーターインジェクションと同じように機能しますが、いくつかのスタイルの利点があります。
-* `inject`は、特にクラスが多くの依存性を注入する場合に、一般的に読みやすくなります。
-* 注入された依存性へのコメント追加が、構文的に見てより簡単です。
-* `inject`はより優れた型推論を提供します。
-* [`useDefineForClassFields`](https://www.typescriptlang.org/tsconfig/#useDefineForClassFields)を使用してES2022+をターゲットにする場合、注入された依存性でフィールドを読み取る際に、フィールド宣言と初期化を分離することを回避できます。
+- `inject`は、特にクラスが多くの依存性を注入する場合に、一般的に読みやすくなります。
+- 注入された依存性へのコメント追加が、構文的に見てより簡単です。
+- `inject`はより優れた型推論を提供します。
+- [`useDefineForClassFields`](https://www.typescriptlang.org/tsconfig/#useDefineForClassFields)を使用してES2022+をターゲットにする場合、注入された依存性でフィールドを読み取る際に、フィールド宣言と初期化を分離することを回避できます。
[既存のコードを自動ツールで`inject`にリファクタリングできます](reference/migrations/inject-function)。
diff --git a/adev-ja/src/content/best-practices/update.en.md b/adev-ja/src/content/best-practices/update.en.md
index 3ce48ce9ae..57297149e8 100644
--- a/adev-ja/src/content/best-practices/update.en.md
+++ b/adev-ja/src/content/best-practices/update.en.md
@@ -6,20 +6,20 @@ Keeping your Angular application up-to-date enables you to take advantage of lea
This document contains information and resources to help you keep your Angular applications and libraries up-to-date.
-For information about our versioning policy and practices —including support and deprecation practices, as well as the release schedule— see [Angular versioning and releases](reference/releases "Angular versioning and releases").
+For information about our versioning policy and practices —including support and deprecation practices, as well as the release schedule— see [Angular versioning and releases](reference/releases 'Angular versioning and releases').
-HELPFUL: If you are currently using AngularJS, see [Upgrading from AngularJS](https://angular.io/guide/upgrade "Upgrading from Angular JS").
-*AngularJS* is the name for all v1.x versions of Angular.
+HELPFUL: If you are currently using AngularJS, see [Upgrading from AngularJS](https://angular.io/guide/upgrade 'Upgrading from Angular JS').
+_AngularJS_ is the name for all v1.x versions of Angular.
## Getting notified of new releases
-To be notified when new releases are available, follow [@angular](https://x.com/angular "@angular on X") on X (formerly Twitter) or subscribe to the [Angular blog](https://blog.angular.dev "Angular blog").
+To be notified when new releases are available, follow [@angular](https://x.com/angular '@angular on X') on X (formerly Twitter) or subscribe to the [Angular blog](https://blog.angular.dev 'Angular blog').
## Learning about new features
-What's new? What's changed? We share the most important things you need to know on the Angular blog in [release announcements]( https://blog.angular.dev/ "Angular blog - release announcements").
+What's new? What's changed? We share the most important things you need to know on the Angular blog in [release announcements](https://blog.angular.dev/ 'Angular blog - release announcements').
-To review a complete list of changes, organized by version, see the [Angular change log](https://github.com/angular/angular/blob/main/CHANGELOG.md "Angular change log").
+To review a complete list of changes, organized by version, see the [Angular change log](https://github.com/angular/angular/blob/main/CHANGELOG.md 'Angular change log').
## Checking your version of Angular
@@ -27,7 +27,7 @@ To check your application's version of Angular use the `ng version` command from
## Finding the current version of Angular
-The most recent stable released version of Angular appears [on npm](https://www.npmjs.com/package/@angular/core "Angular on npm") under "Version." For example, `16.2.4`.
+The most recent stable released version of Angular appears [on npm](https://www.npmjs.com/package/@angular/core 'Angular on npm') under "Version." For example, `16.2.4`.
You can also find the most current version of Angular by using the CLI command [`ng update`](cli/update).
By default, [`ng update`](cli/update)(without additional arguments) lists the updates that are available to you.
@@ -43,22 +43,22 @@ It also includes troubleshooting information and any recommended manual changes
For simple updates, the CLI command [`ng update`](cli/update) is all you need.
Without additional arguments, [`ng update`](cli/update) lists the updates that are available to you and provides recommended steps to update your application to the most current version.
-[Angular Versioning and Releases](reference/releases#versioning "Angular Release Practices, Versioning") describes the level of change that you can expect based on a release's version number.
+[Angular Versioning and Releases](reference/releases#versioning 'Angular Release Practices, Versioning') describes the level of change that you can expect based on a release's version number.
It also describes supported update paths.
## Resource summary
-* Release announcements:
- [Angular blog - release announcements](https://blog.angular.dev/ "Angular blog announcements about recent releases")
+- Release announcements:
+ [Angular blog - release announcements](https://blog.angular.dev/ 'Angular blog announcements about recent releases')
-* Release details:
- [Angular change log](https://github.com/angular/angular/blob/main/CHANGELOG.md "Angular change log")
+- Release details:
+ [Angular change log](https://github.com/angular/angular/blob/main/CHANGELOG.md 'Angular change log')
-* Update instructions:
- [Angular Update Guide](update-guide)
+- Update instructions:
+ [Angular Update Guide](update-guide)
-* Update command reference:
- [Angular CLI `ng update` command reference](cli/update)
+- Update command reference:
+ [Angular CLI `ng update` command reference](cli/update)
-* Versioning, release, support, and deprecation practices:
- [Angular versioning and releases](reference/releases "Angular versioning and releases")
+- Versioning, release, support, and deprecation practices:
+ [Angular versioning and releases](reference/releases 'Angular versioning and releases')
diff --git a/adev-ja/src/content/best-practices/update.md b/adev-ja/src/content/best-practices/update.md
index 021212b0e3..0c2aba53c6 100644
--- a/adev-ja/src/content/best-practices/update.md
+++ b/adev-ja/src/content/best-practices/update.md
@@ -6,20 +6,20 @@ Angularアプリケーションを最新の状態に保つことで、最先端
このドキュメントには、Angularアプリケーションとライブラリを最新の状態に保つための情報とリソースが含まれています。
-バージョン管理ポリシーとプラクティス(サポートと非推奨のプラクティス、リリーススケジュールを含む)については、[Angular バージョン管理とリリース](reference/releases "Angular バージョン管理とリリース")をご覧ください。
+バージョン管理ポリシーとプラクティス(サポートと非推奨のプラクティス、リリーススケジュールを含む)については、[Angular バージョン管理とリリース](reference/releases 'Angular バージョン管理とリリース')をご覧ください。
-HELPFUL: 現在AngularJSを使用している場合は、[AngularJS からのアップグレード](https://angular.io/guide/upgrade "Angular JS からのアップグレード")をご覧ください。
-*AngularJS* は、Angularのすべてのv1.xバージョンを表します。
+HELPFUL: 現在AngularJSを使用している場合は、[AngularJS からのアップグレード](https://angular.io/guide/upgrade 'Angular JS からのアップグレード')をご覧ください。
+_AngularJS_ は、Angularのすべてのv1.xバージョンを表します。
## 新しいリリースの通知を受け取る
-新しいリリースが利用可能になったときに通知を受け取るには、Twitterで [@angular](https://x.com/angular "@angular on X (formerly Twitter)") をフォローするか、[Angular ブログ](https://blog.angular.dev "Angular ブログ")を購読してください。
+新しいリリースが利用可能になったときに通知を受け取るには、X (formerly Twitter)で [@angular](https://x.com/angular '@angular on X') をフォローするか、[Angular ブログ](https://blog.angular.dev 'Angular ブログ')を購読してください。
## 新しい機能について学ぶ
-何が新しくなったのか?何が変わったのか?最新のリリースに関する最も重要な情報をAngularブログの[リリースアナウンスメント]( https://blog.angular.dev/ "Angular ブログ - リリースアナウンスメント")で共有しています。
+何が新しくなったのか?何が変わったのか?最新のリリースに関する最も重要な情報をAngularブログの[リリースアナウンスメント](https://blog.angular.dev/ 'Angular ブログ - リリースアナウンスメント')で共有しています。
-バージョン別に整理された変更の完全なリストを確認するには、[Angularの変更履歴](https://github.com/angular/angular/blob/main/CHANGELOG.md "Angularの変更履歴")をご覧ください。
+バージョン別に整理された変更の完全なリストを確認するには、[Angularの変更履歴](https://github.com/angular/angular/blob/main/CHANGELOG.md 'Angularの変更履歴')をご覧ください。
## Angular のバージョンを確認する
@@ -27,7 +27,7 @@ HELPFUL: 現在AngularJSを使用している場合は、[AngularJS からのア
## Angular の最新バージョンを見つける
-Angularの最新の安定したリリースバージョンは、"Version"の下にある[npm](https://www.npmjs.com/package/@angular/core "Angular on npm")に表示されます。たとえば、`16.2.4`です。
+Angularの最新の安定したリリースバージョンは、"Version"の下にある[npm](https://www.npmjs.com/package/@angular/core 'Angular on npm')に表示されます。たとえば、`16.2.4`です。
また、CLIコマンド [`ng update`](cli/update) を使用して、Angularの最新バージョンを見つけることもできます。
デフォルトでは、[`ng update`](cli/update)(追加の引数なし)は、使用可能なアップデートをリストします。
@@ -43,22 +43,22 @@ Angularアップデートガイドは、指定した現在のバージョンと
簡単なアップデートの場合は、CLIコマンド [`ng update`](cli/update) で十分です。
追加の引数なしで、[`ng update`](cli/update)は、使用可能なアップデートをリストし、アプリケーションを最新バージョンにアップデートするための推奨される手順を提供します。
-[Angularのバージョン管理とリリース](reference/releases#versioning "Angular リリースプラクティス、バージョン管理")では、リリースのバージョン番号に基づいて期待できる変更レベルについて説明しています。
+[Angularのバージョン管理とリリース](reference/releases#versioning 'Angular リリースプラクティス、バージョン管理')では、リリースのバージョン番号に基づいて期待できる変更レベルについて説明しています。
また、サポートされているアップデートパスについても説明しています。
## リソースの概要
-* リリースアナウンスメント:
- [Angular ブログ - リリースに関する最近のアナウンスメント](https://blog.angular.dev/ "Angular ブログの最近のリリースに関するアナウンスメント")
+- リリースアナウンスメント:
+ [Angular ブログ - リリースに関する最近のアナウンスメント](https://blog.angular.dev/ 'Angular ブログの最近のリリースに関するアナウンスメント')
-* リリースの詳細:
- [Angularの変更履歴](https://github.com/angular/angular/blob/main/CHANGELOG.md "Angularの変更履歴")
+- リリースの詳細:
+ [Angularの変更履歴](https://github.com/angular/angular/blob/main/CHANGELOG.md 'Angularの変更履歴')
-* アップデート手順:
- [Angular アップデートガイド](update-guide)
+- アップデート手順:
+ [Angular アップデートガイド](update-guide)
-* アップデートコマンドリファレンス:
- [Angular CLI `ng update` コマンドリファレンス](cli/update)
+- アップデートコマンドリファレンス:
+ [Angular CLI `ng update` コマンドリファレンス](cli/update)
-* バージョン管理、リリース、サポート、および非推奨のプラクティス:
- [Angular バージョン管理とリリース](reference/releases "Angular バージョン管理とリリース")
+- バージョン管理、リリース、サポート、および非推奨のプラクティス:
+ [Angular バージョン管理とリリース](reference/releases 'Angular バージョン管理とリリース')
diff --git a/adev-ja/src/content/cli/index.md b/adev-ja/src/content/cli/index.md
index 76cc1778f2..d6c5d06146 100644
--- a/adev-ja/src/content/cli/index.md
+++ b/adev-ja/src/content/cli/index.md
@@ -10,7 +10,7 @@ Install the CLI using the `npm` package manager:
-npm install -g @angular/cli
+npm install -g @angular/cli
@@ -53,7 +53,7 @@ If the current working directory is not the right place for your project, you ca
## Workspaces and project files
-The [ng new](cli/new) command creates an *Angular workspace* folder and generates a new application skeleton.
+The [ng new](cli/new) command creates an _Angular workspace_ folder and generates a new application skeleton.
A workspace can contain multiple applications and libraries.
The initial application created by the [ng new](cli/new) command is at the top level of the workspace.
When you generate an additional application or library in a workspace, it goes into a `projects/` subfolder.
@@ -65,7 +65,7 @@ You can edit the generated files directly, or add to and modify them using CLI c
Use the [ng generate](cli/generate) command to add new files for additional components and services, and code for new pipes, directives, and so on.
Commands such as [add](cli/add) and [generate](cli/generate), which create or operate on applications and libraries, must be executed from within a workspace or project folder.
-* See more about the [Workspace file structure](guide/file-structure).
+- See more about the [Workspace file structure](guide/file-structure).
### Workspace and project configuration
@@ -81,32 +81,32 @@ Option names in the configuration file must use [camelCase](guide/glossary#case-
-* See more about [Workspace Configuration](guide/workspace-config).
+- See more about [Workspace Configuration](guide/workspace-config).
## CLI command-language syntax
Command syntax is shown as follows:
-`ng` ** ** [*optional-arg*] `[options]`
+`ng` __ __ [*optional-arg*] `[options]`
-* Most commands, and some options, have aliases.
- Aliases are shown in the syntax statement for each command.
+- Most commands, and some options, have aliases.
+ Aliases are shown in the syntax statement for each command.
-* Option names are prefixed with a double dash \(`--`\) characters.
- Option aliases are prefixed with a single dash \(`-`\) character.
- Arguments are not prefixed.
- For example:
+- Option names are prefixed with a double dash \(`--`\) characters.
+ Option aliases are prefixed with a single dash \(`-`\) character.
+ Arguments are not prefixed.
+ For example:
-
+
- ng build my-app -c production
+ ng build my-app -c production
-
+
-* Typically, the name of a generated artifact can be given as an argument to the command or specified with the `--name` option.
+- Typically, the name of a generated artifact can be given as an argument to the command or specified with the `--name` option.
-* Arguments and option names must be given in [dash-case](guide/glossary#case-types).
- For example: `--my-option-name`
+- Arguments and option names must be given in [dash-case](guide/glossary#case-types).
+ For example: `--my-option-name`
### Boolean options
@@ -124,7 +124,7 @@ Options that specify files can be given as absolute paths, or as paths relative
### Schematics
The [ng generate](cli/generate) and [ng add](cli/add) commands take, as an argument, the artifact or library to be generated or added to the current project.
-In addition to any general options, each artifact or library defines its own options in a *schematic*.
+In addition to any general options, each artifact or library defines its own options in a _schematic_.
Schematic options are supplied to the command in the same format as immediate command options.
diff --git a/adev-ja/src/content/ecosystem/custom-build-pipeline.en.md b/adev-ja/src/content/ecosystem/custom-build-pipeline.en.md
index 10d2aa4a0d..6670076a62 100644
--- a/adev-ja/src/content/ecosystem/custom-build-pipeline.en.md
+++ b/adev-ja/src/content/ecosystem/custom-build-pipeline.en.md
@@ -8,9 +8,9 @@ This page explores the **rare use cases** when you need a custom build pipeline
There are some niche use cases when you may want to maintain a custom build pipeline. For example:
-* You have an existing app using a different toolchain and you’d like to add Angular to it
-* You’re strongly coupled to [module federation](https://module-federation.io/) and unable to adopt bundler-agnostic [native federation](https://www.npmjs.com/package/@angular-architects/native-federation)
-* You’d like to create an short-lived experiment using your favorite build tool
+- You have an existing app using a different toolchain and you’d like to add Angular to it
+- You’re strongly coupled to [module federation](https://module-federation.io/) and unable to adopt bundler-agnostic [native federation](https://www.npmjs.com/package/@angular-architects/native-federation)
+- You’d like to create an short-lived experiment using your favorite build tool
## What are the options?
diff --git a/adev-ja/src/content/ecosystem/custom-build-pipeline.md b/adev-ja/src/content/ecosystem/custom-build-pipeline.md
index c804d89542..f2f9068615 100644
--- a/adev-ja/src/content/ecosystem/custom-build-pipeline.md
+++ b/adev-ja/src/content/ecosystem/custom-build-pipeline.md
@@ -8,9 +8,9 @@ Angularアプリケーションを構築する際、Angular CLIを使用して
カスタムビルドパイプラインを維持したいニッチなユースケースがいくつかあります。次に例を示します。
-* 異なるツールチェーンを使用している既存のアプリケーションがあり、それにAngularを追加したい場合
-* [モジュールフェデレーション](https://module-federation.io/)に強く結びついており、バンドラーに依存しない[ネイティブフェデレーション](https://www.npmjs.com/package/@angular-architects/native-federation)を採用できない場合
-* お気に入りのビルドツールを使用して、短期間の実験を作成したい場合
+- 異なるツールチェーンを使用している既存のアプリケーションがあり、それにAngularを追加したい場合
+- [モジュールフェデレーション](https://module-federation.io/)に強く結びついており、バンドラーに依存しない[ネイティブフェデレーション](https://www.npmjs.com/package/@angular-architects/native-federation)を採用できない場合
+- お気に入りのビルドツールを使用して、短期間の実験を作成したい場合
## どのような選択肢がありますか?
diff --git a/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md b/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md
index 207a1f66b0..bd9faff699 100644
--- a/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md
+++ b/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md
@@ -8,18 +8,18 @@ The `@angular/rxjs-interop` package offers two APIs related to component and dir
The `outputFromObservable` lets you create a component or directive output that emits based on an RxJS observable:
-
+```ts {highlight:[9]}
import {Directive} from '@angular/core';
import {outputFromObservable} from '@angular/core/rxjs-interop';
@Directive({/*...*/})
class Draggable {
- pointerMoves$: Observable = listenToPointerMoves();
-
- // Whenever `pointerMoves$` emits, the `pointerMove` event fires.
- pointerMove = outputFromObservable(this.pointerMoves$);
+ pointerMoves$: Observable = listenToPointerMoves();
+
+ // Whenever `pointerMoves$` emits, the `pointerMove` event fires.
+ pointerMove = outputFromObservable(this.pointerMoves$);
}
-
+```
The `outputFromObservable` function has special meaning to the Angular compiler. **You may only call `outputFromObservable` in component and directive property initializers.**
@@ -31,20 +31,20 @@ HELPFUL: Consider using `output()` directly if you can emit values imperatively.
The `outputToObservable` function lets you create an RxJS observable from a component output.
-
+```ts {highlight:[11]}
import {outputToObservable} from '@angular/core/rxjs-interop';
@Component(/*...*/)
-class CustomSlider {
- valueChange = output();
+ class CustomSlider {
+ valueChange = output();
}
// Instance reference to `CustomSlider`.
const slider: CustomSlider = createSlider();
outputToObservable(slider.valueChange) // Observable
- .pipe(...)
- .subscribe(...);
-
+ .pipe(...)
+ .subscribe(...);
+```
HELPFUL: Consider using the `subscribe` method on `OutputRef` directly if it meets your needs.
diff --git a/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md b/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md
index 210311cc30..2ab060e0cd 100644
--- a/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md
+++ b/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md
@@ -6,7 +6,7 @@ The `@angular/core/rxjs-interop` package offers APIs that help you integrate RxJ
Use the `toSignal` function to create a signal which tracks the value of an Observable. It behaves similarly to the `async` pipe in templates, but is more flexible and can be used anywhere in an application.
-```ts
+```angular-ts
import { Component } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { interval } from 'rxjs';
@@ -55,6 +55,31 @@ By default, `toSignal` automatically unsubscribes from the Observable when the c
To override this behavior, you can pass the `manualCleanup` option. You can use this setting for Observables that complete themselves naturally.
+#### Custom equality comparison
+
+Some observables may emit values that are **equals** even though they differ by reference or minor detail. The `equal` option lets you define a **custom equal function** to determine when two consecutive values should be considered the same.
+
+When two emitted values are considered equal, the resulting signal **does not update**. This prevents redundant computations, DOM updates, or effects from re-running unnecessarily.
+
+```ts
+import { Component } from '@angular/core';
+import { toSignal } from '@angular/core/rxjs-interop';
+import { interval, map } from 'rxjs';
+
+@Component(/* ... */)
+export class EqualExample {
+ temperature$ = interval(1000).pipe(
+ map(() => ({ temperature: Math.floor(Math.random() * 3) + 20 }) ) // 20, 21, or 22 randomly
+ );
+
+ // Only update if the temperature changes
+ temperature = toSignal(this.temperature$, {
+ initialValue: { temperature : 20 },
+ equal: (prev, curr) => prev.temperature === curr.temperature
+ });
+}
+```
+
### Error and Completion
If an Observable used in `toSignal` produces an error, that error is thrown when the signal is read.
@@ -121,7 +146,7 @@ export class UserProfile {
protected userId = input();
private userResource = rxResource({
- params: () => this.userId(),
+ params: () => ({ userId: this.userId() }),
// The `stream` property expects a factory function that returns
// a data stream as an RxJS Observable.
diff --git a/adev-ja/src/content/ecosystem/service-workers/app-shell.md b/adev-ja/src/content/ecosystem/service-workers/app-shell.md
index e4fdf2fb47..31e86a0a83 100644
--- a/adev-ja/src/content/ecosystem/service-workers/app-shell.md
+++ b/adev-ja/src/content/ecosystem/service-workers/app-shell.md
@@ -9,22 +9,18 @@ This gives users a meaningful first paint of your application that appears quick
Do this with the following Angular CLI command:
-
-
+```shell
ng new my-app
-
-
+```
For an existing application, you have to manually add the `Router` and defining a `` within your application.
Use the Angular CLI to automatically create the application shell.
-
-
+```shell
ng generate app-shell
-
-
+```
For more information about this command, see [App shell command](cli/generate/app-shell).
@@ -44,19 +40,15 @@ src
-
-
+```shell
ng build --configuration=development
-
-
+```
Or to use the production configuration.
-
-
+```shell
ng build
-
-
+```
To verify the build output, open dist/my-app/browser/index.html.
Look for default text `app-shell works!` to show that the application shell route was rendered as part of the output.
diff --git a/adev-ja/src/content/ecosystem/service-workers/communications.md b/adev-ja/src/content/ecosystem/service-workers/communications.md
index 59ab2db13d..71e9ffe51b 100644
--- a/adev-ja/src/content/ecosystem/service-workers/communications.md
+++ b/adev-ja/src/content/ecosystem/service-workers/communications.md
@@ -8,20 +8,20 @@ The `SwUpdate` service gives you access to events that indicate when the service
The `SwUpdate` service supports three separate operations:
-* Receiving notifications when an updated version is *detected* on the server, *installed and ready* to be used locally or when an *installation fails*.
-* Asking the service worker to check the server for new updates.
-* Asking the service worker to activate the latest version of the application for the current tab.
+- Receiving notifications when an updated version is _detected_ on the server, _installed and ready_ to be used locally or when an _installation fails_.
+- Asking the service worker to check the server for new updates.
+- Asking the service worker to activate the latest version of the application for the current tab.
### Version updates
The `versionUpdates` is an `Observable` property of `SwUpdate` and emits five event types:
-| Event types | Details |
-|:--- |:--- |
-| `VersionDetectedEvent` | Emitted when the service worker has detected a new version of the app on the server and is about to start downloading it. |
-| `NoNewVersionDetectedEvent` | Emitted when the service worker has checked the version of the app on the server and did not find a new version. |
-| `VersionReadyEvent` | Emitted when a new version of the app is available to be activated by clients. It may be used to notify the user of an available update or prompt them to refresh the page. |
-| `VersionInstallationFailedEvent` | Emitted when the installation of a new version failed. It may be used for logging/monitoring purposes. |
+| Event types | Details |
+| :------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `VersionDetectedEvent` | Emitted when the service worker has detected a new version of the app on the server and is about to start downloading it. |
+| `NoNewVersionDetectedEvent` | Emitted when the service worker has checked the version of the app on the server and did not find a new version. |
+| `VersionReadyEvent` | Emitted when a new version of the app is available to be activated by clients. It may be used to notify the user of an available update or prompt them to refresh the page. |
+| `VersionInstallationFailedEvent` | Emitted when the installation of a new version failed. It may be used for logging/monitoring purposes. |
| `VersionFailedEvent` | Emitted when a version encounters a critical failure (such as broken hash errors) that affects all clients using that version. Provides error details for debugging and transparency. |
@@ -73,23 +73,23 @@ In some cases, the version of the application used by the service worker to serv
For example, imagine the following scenario:
1. A user opens the application for the first time and the service worker caches the latest version of the application.
- Assume the application's cached assets include `index.html`, `main..js` and `lazy-chunk..js`.
+ Assume the application's cached assets include `index.html`, `main..js` and `lazy-chunk..js`.
1. The user closes the application and does not open it for a while.
1. After some time, a new version of the application is deployed to the server.
- This newer version includes the files `index.html`, `main..js` and `lazy-chunk..js`.
+ This newer version includes the files `index.html`, `main..js` and `lazy-chunk..js`.
IMPORTANT: The hashes are different now, because the content of the files changed. The old version is no longer available on the server.
1. In the meantime, the user's browser decides to evict `lazy-chunk..js` from its cache.
- Browsers might decide to evict specific (or all) resources from a cache in order to reclaim disk space.
+ Browsers might decide to evict specific (or all) resources from a cache in order to reclaim disk space.
1. The user opens the application again.
- The service worker serves the latest version known to it at this point, namely the old version (`index.html` and `main..js`).
+ The service worker serves the latest version known to it at this point, namely the old version (`index.html` and `main..js`).
1. At some later point, the application requests the lazy bundle, `lazy-chunk..js`.
1. The service worker is unable to find the asset in the cache (remember that the browser evicted it).
- Nor is it able to retrieve it from the server (because the server now only has `lazy-chunk..js` from the newer version).
+ Nor is it able to retrieve it from the server (because the server now only has `lazy-chunk..js` from the newer version).
In the preceding scenario, the service worker is not able to serve an asset that would normally be cached.
That particular application version is broken and there is no way to fix the state of the client without reloading the page.
diff --git a/adev-ja/src/content/ecosystem/service-workers/config.md b/adev-ja/src/content/ecosystem/service-workers/config.md
index 1cdf056d34..ba05a1d7ba 100644
--- a/adev-ja/src/content/ecosystem/service-workers/config.md
+++ b/adev-ja/src/content/ecosystem/service-workers/config.md
@@ -9,10 +9,10 @@ The [Angular CLI](tools/cli) processes this configuration file during `ng build`
All file paths must begin with `/`, which corresponds to the deployment directory — usually `dist/` in CLI projects.
-Unless otherwise commented, patterns use a **limited*** glob format that internally will be converted into regex:
+Unless otherwise commented, patterns use a **limited\*** glob format that internally will be converted into regex:
-| Glob formats | Details |
-|:--- |:--- |
+| Glob formats | Details |
+| :----------- | :----------------------------------------------------------------------------------------------------- |
| `**` | Matches 0 or more path segments |
| `*` | Matches 0 or more characters excluding `/` |
| `?` | Matches exactly one character excluding `/` |
@@ -32,8 +32,8 @@ If you want your patterns to match the beginning and/or end of URLs, you can add
Example patterns:
-| Patterns | Details |
-|:--- |:--- |
+| Patterns | Details |
+| :----------- | :------------------------------------ |
| `/**/*.html` | Specifies all HTML files |
| `/*.html` | Specifies only HTML files in the root |
| `!/**/*.map` | Exclude all sourcemaps |
@@ -55,7 +55,7 @@ Usually this is `/index.html`.
### `assetGroups`
-*Assets* are resources that are part of the application version that update along with the application.
+_Assets_ are resources that are part of the application version that update along with the application.
They can include resources loaded from the page's origin as well as third-party resources loaded from CDNs and other external URLs.
As not all such external URLs might be known at build time, URL patterns can be matched.
@@ -63,8 +63,7 @@ HELPFUL: For the service worker to handle resources that are loaded from differe
This field contains an array of asset groups, each of which defines a set of asset resources and the policy by which they are cached.
-
-
+```ts
{
"assetGroups": [
{
@@ -75,8 +74,7 @@ This field contains an array of asset groups, each of which defines a set of ass
}
]
}
-
-
+```
HELPFUL: When the ServiceWorker handles a request, it checks asset groups in the order in which they appear in `ngsw-config.json`.
The first asset group that matches the requested resource handles the request.
@@ -89,8 +87,7 @@ This policy determines when the resources are fetched and what happens when chan
Asset groups follow the Typescript interface shown here:
-
-
+```ts
interface AssetGroup {
name: string;
installMode?: 'prefetch' | 'lazy';
@@ -103,8 +100,7 @@ interface AssetGroup {
ignoreSearch?: boolean;
};
}
-
-
+```
Each `AssetGroup` is defined by the following asset group properties.
@@ -118,8 +114,8 @@ It identifies this particular group of assets between versions of the configurat
The `installMode` determines how these resources are initially cached.
The `installMode` can be either of two values:
-| Values | Details |
-|:--- |:--- |
+| Values | Details |
+| :--------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `prefetch` | Tells the Angular service worker to fetch every single listed resource while it's caching the current version of the application. This is bandwidth-intensive but ensures resources are available whenever they're requested, even if the browser is currently offline. |
| `lazy` | Does not cache any of the resources up front. Instead, the Angular service worker only caches resources for which it receives requests. This is an on-demand caching mode. Resources that are never requested are not cached. This is useful for things like images at different resolutions, so the service worker only caches the correct assets for the particular screen and orientation. |
@@ -130,8 +126,8 @@ Defaults to `prefetch`.
For resources already in the cache, the `updateMode` determines the caching behavior when a new version of the application is discovered.
Any resources in the group that have changed since the previous version are updated in accordance with `updateMode`.
-| Values | Details |
-|:--- |:--- |
+| Values | Details |
+| :--------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `prefetch` | Tells the service worker to download and cache the changed resources immediately. |
| `lazy` | Tells the service worker to not cache those resources. Instead, it treats them as unrequested and waits until they're requested again before updating them. An `updateMode` of `lazy` is only valid if the `installMode` is also `lazy`. |
@@ -141,10 +137,10 @@ Defaults to the value `installMode` is set to.
This section describes the resources to cache, broken up into the following groups:
-| Resource groups | Details |
-|:--- |:--- |
-| `files` | Lists patterns that match files in the distribution directory. These can be single files or glob-like patterns that match a number of files. |
-| `urls` | Includes both URLs and URL patterns that are matched at runtime. These resources are not fetched directly and do not have content hashes, but they are cached according to their HTTP headers. This is most useful for CDNs such as the Google Fonts service. *(Negative glob patterns are not supported and `?` will be matched literally; that is, it will not match any character other than `?`.)* |
+| Resource groups | Details |
+| :-------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `files` | Lists patterns that match files in the distribution directory. These can be single files or glob-like patterns that match a number of files. |
+| `urls` | Includes both URLs and URL patterns that are matched at runtime. These resources are not fetched directly and do not have content hashes, but they are cached according to their HTTP headers. This is most useful for CDNs such as the Google Fonts service. _(Negative glob patterns are not supported and `?` will be matched literally; that is, it will not match any character other than `?`.)_ |
#### `cacheQueryOptions`
@@ -153,8 +149,8 @@ They are passed to the browsers `Cache#match` function.
See [MDN](https://developer.mozilla.org/docs/Web/API/Cache/match) for details.
Currently, only the following options are supported:
-| Options | Details |
-|:--- |:--- |
+| Options | Details |
+| :------------- | :-------------------------------------------- |
| `ignoreSearch` | Ignore query parameters. Defaults to `false`. |
### `dataGroups`
@@ -164,8 +160,7 @@ They're cached according to manually-configured policies that are more useful fo
This field contains an array of data groups, each of which defines a set of data resources and the policy by which they are cached.
-
-
+```json
{
"dataGroups": [
{
@@ -176,8 +171,7 @@ This field contains an array of data groups, each of which defines a set of data
}
]
}
-
-
+```
HELPFUL: When the ServiceWorker handles a request, it checks data groups in the order in which they appear in `ngsw-config.json`.
The first data group that matches the requested resource handles the request.
@@ -187,8 +181,7 @@ For example, a data group that matches `/api/foo.json` should appear before one
Data groups follow this Typescript interface:
-
-
+```ts
export interface DataGroup {
name: string;
urls: string[];
@@ -204,8 +197,7 @@ export interface DataGroup {
ignoreSearch?: boolean;
};
}
-
-
+```
Each `DataGroup` is defined by the following data group properties.
@@ -219,8 +211,8 @@ A list of URL patterns.
URLs that match these patterns are cached according to this data group's policy.
Only non-mutating requests (GET and HEAD) are cached.
-* Negative glob patterns are not supported
-* `?` is matched literally; that is, it matches *only* the character `?`
+- Negative glob patterns are not supported
+- `?` is matched literally; that is, it matches _only_ the character `?`
#### `version`
@@ -245,8 +237,8 @@ CRITICAL: Open-ended caches can grow in unbounded ways and eventually exceed sto
The `maxAge` parameter indicates how long responses are allowed to remain in the cache before being considered invalid and evicted. `maxAge` is a duration string, using the following unit suffixes:
-| Suffixes | Details |
-|:--- |:--- |
+| Suffixes | Details |
+| :------- | :----------- |
| `d` | Days |
| `h` | Hours |
| `m` | Minutes |
@@ -261,8 +253,8 @@ This duration string specifies the network timeout.
The network timeout is how long the Angular service worker waits for the network to respond before using a cached response, if configured to do so.
`timeout` is a duration string, using the following unit suffixes:
-| Suffixes | Details |
-|:--- |:--- |
+| Suffixes | Details |
+| :------- | :----------- |
| `d` | Days |
| `h` | Hours |
| `m` | Minutes |
@@ -271,14 +263,13 @@ The network timeout is how long the Angular service worker waits for the network
For example, the string `5s30u` translates to five seconds and 30 milliseconds of network timeout.
-
##### `refreshAhead`
This duration string specifies the time ahead of the expiration of a cached resource when the Angular service worker should proactively attempt to refresh the resource from the network.
The `refreshAhead` duration is an optional configuration that determines how much time before the expiration of a cached response the service worker should initiate a request to refresh the resource from the network.
-| Suffixes | Details |
-|:--- |:--- |
+| Suffixes | Details |
+| :------- | :----------- |
| `d` | Days |
| `h` | Hours |
| `m` | Minutes |
@@ -291,8 +282,8 @@ For example, the string `1h30m` translates to one hour and 30 minutes ahead of t
The Angular service worker can use either of two caching strategies for data resources.
-| Caching strategies | Details |
-|:--- |:--- |
+| Caching strategies | Details |
+| :----------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `performance` | The default, optimizes for responses that are as fast as possible. If a resource exists in the cache, the cached version is used, and no network request is made. This allows for some staleness, depending on the `maxAge`, in exchange for better performance. This is suitable for resources that don't change often; for example, user avatar images. |
| `freshness` | Optimizes for currency of data, preferentially fetching requested data from the network. Only if the network times out, according to `timeout`, does the request fall back to the cache. This is useful for resources that change frequently; for example, account balances. |
@@ -312,9 +303,9 @@ Whether the Angular service worker should cache opaque responses or not.
If not specified, the default value depends on the data group's configured strategy:
-| Strategies | Details |
-|:--- |:--- |
-| Groups with the `freshness` strategy | The default value is `true` and the service worker caches opaque responses. These groups will request the data every time and only fall back to the cached response when offline or on a slow network. Therefore, it doesn't matter if the service worker caches an error response. |
+| Strategies | Details |
+| :------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Groups with the `freshness` strategy | The default value is `true` and the service worker caches opaque responses. These groups will request the data every time and only fall back to the cached response when offline or on a slow network. Therefore, it doesn't matter if the service worker caches an error response. |
| Groups with the `performance` strategy | The default value is `false` and the service worker doesn't cache opaque responses. These groups would continue to return a cached response until `maxAge` expires, even if the error was due to a temporary network or server issue. Therefore, it would be problematic for the service worker to cache an error response. |
@@ -340,14 +331,14 @@ This optional section enables you to specify a custom list of URLs that will be
The ServiceWorker redirects navigation requests that don't match any `asset` or `data` group to the specified [index file](#index).
A request is considered to be a navigation request if:
-* Its [method](https://developer.mozilla.org/docs/Web/API/Request/method) is `GET`
-* Its [mode](https://developer.mozilla.org/docs/Web/API/Request/mode) is `navigation`
-* It accepts a `text/html` response as determined by the value of the `Accept` header
-* Its URL matches the following criteria:
- * The URL must not contain a file extension (that is, a `.`) in the last path segment
- * The URL must not contain `__`
+- Its [method](https://developer.mozilla.org/docs/Web/API/Request/method) is `GET`
+- Its [mode](https://developer.mozilla.org/docs/Web/API/Request/mode) is `navigation`
+- It accepts a `text/html` response as determined by the value of the `Accept` header
+- Its URL matches the following criteria:
+ - The URL must not contain a file extension (that is, a `.`) in the last path segment
+ - The URL must not contain `__`
-HELPFUL: To configure whether navigation requests are sent through to the network or not, see the [navigationRequestStrategy](#navigationrequeststrategy) section and [applicationMaxAge](#application-max-age) sections.
+HELPFUL: To configure whether navigation requests are sent through to the network or not, see the [navigationRequestStrategy](#navigationrequeststrategy) section and [applicationMaxAge](#applicationmaxage) sections.
#### Matching navigation request URLs
@@ -357,21 +348,21 @@ For example, you might want to ignore specific routes, such as those that are no
This field contains an array of URLs and [glob-like](#modifying-the-configuration) URL patterns that are matched at runtime.
It can contain both negative patterns (that is, patterns starting with `!`) and non-negative patterns and URLs.
-Only requests whose URLs match *any* of the non-negative URLs/patterns and *none* of the negative ones are considered navigation requests.
+Only requests whose URLs match _any_ of the non-negative URLs/patterns and _none_ of the negative ones are considered navigation requests.
The URL query is ignored when matching.
If the field is omitted, it defaults to:
-
+```ts
[
- '/**', // Include all URLs.
- '!/**/*.*', // Exclude URLs to files (containing a file extension in the last segment).
- '!/**/*__*', // Exclude URLs containing `__` in the last segment.
- '!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
+'/**', // Include all URLs.
+'!/**/*.*', // Exclude URLs to files (containing a file extension in the last segment).
+'!/**/*__*', // Exclude URLs containing `__` in the last segment.
+'!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
]
-
+```
### `navigationRequestStrategy`
@@ -380,14 +371,14 @@ This optional property enables you to configure how the service worker handles n
{
- "navigationRequestStrategy": "freshness"
+"navigationRequestStrategy": "freshness"
}
-| Possible values | Details |
-|:--- |:--- |
-| `'performance'` | The default setting. Serves the specified [index file](#index-file), which is typically cached. |
+| Possible values | Details |
+| :-------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `'performance'` | The default setting. Serves the specified [index file](#index), which is typically cached. |
| `'freshness'` | Passes the requests through to the network and falls back to the `performance` behavior when offline. This value is useful when the server redirects the navigation requests elsewhere using a `3xx` HTTP redirect status code. Reasons for using this value include:
Redirecting to an authentication website when authentication is not handled by the application
Redirecting specific URLs to avoid breaking existing links/bookmarks after a website redesign
Redirecting to a different website, such as a server-status page, while a page is temporarily down
|
IMPORTANT: The `freshness` strategy usually results in more requests sent to the server, which can increase response latency. It is recommended that you use the default performance strategy whenever possible.
diff --git a/adev-ja/src/content/ecosystem/service-workers/custom-service-worker-scripts.md b/adev-ja/src/content/ecosystem/service-workers/custom-service-worker-scripts.md
index 8bafac8159..d5fdcaa6dd 100644
--- a/adev-ja/src/content/ecosystem/service-workers/custom-service-worker-scripts.md
+++ b/adev-ja/src/content/ecosystem/service-workers/custom-service-worker-scripts.md
@@ -8,8 +8,7 @@ To create a custom service worker that extends Angular's functionality:
1. Create a custom service worker file (e.g., `custom-sw.js`) in your `src` directory:
-
-
+```js
// Import the Angular service worker
importScripts('./ngsw-worker.js');
@@ -20,7 +19,7 @@ importScripts('./ngsw-worker.js');
self.addEventListener('notificationclick', (event) => {
console.log('Custom notification click handler');
console.log('Notification details:', event.notification);
-
+
// Handle notification click - open URL if provided
if (clients.openWindow && event.notification.data.url) {
event.waitUntil(clients.openWindow(event.notification.data.url));
@@ -31,7 +30,7 @@ importScripts('./ngsw-worker.js');
// Add custom background sync handler
self.addEventListener('sync', (event) => {
console.log('Custom background sync handler');
-
+
if (event.tag === 'background-sync') {
event.waitUntil(doBackgroundSync());
}
@@ -40,44 +39,40 @@ importScripts('./ngsw-worker.js');
function doBackgroundSync() {
// Implement your background sync logic here
return fetch('https://example.com/api/sync')
- .then(response => response.json())
- .then(data => console.log('Background sync completed:', data))
- .catch(error => console.error('Background sync failed:', error));
+ .then((response) => response.json())
+ .then((data) => console.log('Background sync completed:', data))
+ .catch((error) => console.error('Background sync failed:', error));
}
})();
-
-
+```
2. Update your `angular.json` file to use the custom service worker:
-
-
+```json
{
"projects": {
"your-app": {
"architect": {
"build": {
- "options": {
- "assets": [
- {
+ "options": {
+ "assets": [
+ {
"glob": "**/*",
"input": "public"
- },
- "app/src/custom-sw.js"
- ]
- },
+ },
+ "app/src/custom-sw.js"
+ ]
+ }
}
}
}
}
}
-
-
+```
3. Configure the service worker registration to use your custom script:
-
-
+```ts
import { ApplicationConfig, isDevMode } from '@angular/core';
import { provideServiceWorker } from '@angular/service-worker';
@@ -85,12 +80,11 @@ export const appConfig: ApplicationConfig = {
providers: [
provideServiceWorker('custom-sw.js', {
enabled: !isDevMode(),
- registrationStrategy: 'registerWhenStable:30000'
+ registrationStrategy: 'registerWhenStable:30000',
}),
],
};
-
-
+```
### Best practices for custom service workers
@@ -107,5 +101,5 @@ When extending the Angular service worker:
Custom service workers are commonly used for:
- **Push notifications**: Handle incoming push messages and display notifications
-- **Background sync**: Sync data when the network connection is restored
+- **Background sync**: Sync data when the network connection is restored
- **Custom navigation**: Handle special routing or offline page scenarios
diff --git a/adev-ja/src/content/ecosystem/service-workers/devops.md b/adev-ja/src/content/ecosystem/service-workers/devops.md
index 4aea23e743..fb3b0ea921 100644
--- a/adev-ja/src/content/ecosystem/service-workers/devops.md
+++ b/adev-ja/src/content/ecosystem/service-workers/devops.md
@@ -60,17 +60,17 @@ If necessary, the service worker enters a safe mode where requests fall back on
Hash mismatches can occur for a variety of reasons:
-* Caching layers between the origin server and the end user could serve stale content
-* A non-atomic deployment could result in the Angular service worker having visibility of partially updated content
-* Errors during the build process could result in updated resources without `ngsw.json` being updated.
- The reverse could also happen resulting in an updated `ngsw.json` without updated resources.
+- Caching layers between the origin server and the end user could serve stale content
+- A non-atomic deployment could result in the Angular service worker having visibility of partially updated content
+- Errors during the build process could result in updated resources without `ngsw.json` being updated.
+ The reverse could also happen resulting in an updated `ngsw.json` without updated resources.
#### Unhashed content
The only resources that have hashes in the `ngsw.json` manifest are resources that were present in the `dist` directory at the time the manifest was built.
Other resources, especially those loaded from CDNs, have content that is unknown at build time or are updated more frequently than the application is deployed.
-If the Angular service worker does not have a hash to verify a resource is valid, it still caches its contents. At the same time, it honors the HTTP caching headers by using a policy of *stale while revalidate*.
+If the Angular service worker does not have a hash to verify a resource is valid, it still caches its contents. At the same time, it honors the HTTP caching headers by using a policy of _stale while revalidate_.
The Angular service worker continues to serve a resource even after its HTTP caching headers indicate
that it is no longer valid. At the same time, it attempts to refresh the expired resource in the background.
This way, broken unhashed resources do not remain in the cache beyond their configured lifetimes.
@@ -88,15 +88,15 @@ IMPORTANT: This guarantee is **stronger** than that provided by the normal web d
The Angular service worker might change the version of a running application under error conditions such as:
-* The current version becomes non-valid due to a failed hash.
-* An unrelated error causes the service worker to enter safe mode and deactivates it temporarily.
+- The current version becomes non-valid due to a failed hash.
+- An unrelated error causes the service worker to enter safe mode and deactivates it temporarily.
The Angular service worker cleans up application versions when no tab is using them.
Other reasons the Angular service worker might change the version of a running application are normal events:
-* The page is reloaded/refreshed.
-* The page requests an update be immediately activated using the `SwUpdate` service.
+- The page is reloaded/refreshed.
+- The page requests an update be immediately activated using the `SwUpdate` service.
### Service worker updates
@@ -155,7 +155,8 @@ Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100
Last update tick: 1s496u
Last update run: never
Task queue:
- * init post-load (update, cleanup)
+
+- init post-load (update, cleanup)
Debug log:
@@ -175,10 +176,10 @@ Driver state: NORMAL ((nominal))
There are two possible degraded states:
-| Degraded states | Details |
-|:--- |:--- |
+| Degraded states | Details |
+| :---------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `EXISTING_CLIENTS_ONLY` | The service worker does not have a clean copy of the latest known version of the application. Older cached versions are safe to use, so existing tabs continue to run from cache, but new loads of the application will be served from the network. The service worker will try to recover from this state when a new version of the application is detected and installed. This happens when a new `ngsw.json` is available. |
-| `SAFE_MODE` | The service worker cannot guarantee the safety of using cached data. Either an unexpected error occurred or all cached versions are invalid. All traffic will be served from the network, running as little service worker code as possible. |
+| `SAFE_MODE` | The service worker cannot guarantee the safety of using cached data. Either an unexpected error occurred or all cached versions are invalid. All traffic will be served from the network, running as little service worker code as possible. |
In both cases, the parenthetical annotation provides the
error that caused the service worker to enter the degraded state.
@@ -232,7 +233,8 @@ HELPFUL: This version hash is the "latest manifest hash" listed above. Both clie
Last update tick: 1s496u
Last update run: never
Task queue:
- * init post-load (update, cleanup)
+
+- init post-load (update, cleanup)
@@ -259,13 +261,13 @@ Errors that occur within the service worker are logged here.
Browsers such as Chrome provide developer tools for interacting with service workers.
Such tools can be powerful when used properly, but there are a few things to keep in mind.
-* When using developer tools, the service worker is kept running in the background and never restarts.
- This can cause behavior with Dev Tools open to differ from behavior a user might experience.
+- When using developer tools, the service worker is kept running in the background and never restarts.
+ This can cause behavior with Dev Tools open to differ from behavior a user might experience.
-* If you look in the Cache Storage viewer, the cache is frequently out of date.
- Right-click the Cache Storage title and refresh the caches.
+- If you look in the Cache Storage viewer, the cache is frequently out of date.
+ Right-click the Cache Storage title and refresh the caches.
-* Stopping and starting the service worker in the Service Worker pane checks for updates
+- Stopping and starting the service worker in the Service Worker pane checks for updates
## Service worker safety
diff --git a/adev-ja/src/content/ecosystem/service-workers/getting-started.md b/adev-ja/src/content/ecosystem/service-workers/getting-started.md
index aedaeb7f6e..268a3a1870 100644
--- a/adev-ja/src/content/ecosystem/service-workers/getting-started.md
+++ b/adev-ja/src/content/ecosystem/service-workers/getting-started.md
@@ -6,11 +6,11 @@ This document explains how to enable Angular service worker support in projects
To set up the Angular service worker in your project, run the following CLI command:
-
+```shell
ng add @angular/pwa
-
+```
The CLI configures your application to use service workers with the following actions:
@@ -18,19 +18,19 @@ The CLI configures your application to use service workers with the following ac
1. Enables service worker build support in the CLI.
1. Imports and registers the service worker with the application's root providers.
1. Updates the `index.html` file:
- * Includes a link to add the `manifest.webmanifest` file
- * Adds a meta tag for `theme-color`
+ - Includes a link to add the `manifest.webmanifest` file
+ - Adds a meta tag for `theme-color`
1. Installs icon files to support the installed Progressive Web App (PWA).
1. Creates the service worker configuration file called [`ngsw-config.json`](ecosystem/service-workers/config),
-which specifies the caching behaviors and other settings.
+ which specifies the caching behaviors and other settings.
Now, build the project:
-
+```shell
ng build
-
+```
The CLI project is now set up to use the Angular service worker.
@@ -39,20 +39,20 @@ The CLI project is now set up to use the Angular service worker.
This section demonstrates a service worker in action,
using an example application. To enable service worker support during local development, use the production configuration with the following command:
-
+```shell
ng serve --configuration=production
-
+```
Alternatively, you can use the [`http-server package`](https://www.npmjs.com/package/http-server) from
npm, which supports service worker applications. Run it without installation using:
-
+```shell
-npx http-server -p 8080 -c-1 dist/<project-name>/browser
+npx http-server -p 8080 -c-1 dist//browser
-
+```
This will serve your application with service worker support at http://localhost:8080.
@@ -97,12 +97,12 @@ Instead, they are being loaded from the service worker's cache.
Notice that all of the files the browser needs to render this application are cached.
The `ngsw-config.json` boilerplate configuration is set up to cache the specific resources used by the CLI:
-* `index.html`
-* `favicon.ico`
-* Build artifacts (JS and CSS bundles)
-* Anything under `assets`
-* Images and fonts directly under the configured `outputPath` (by default `./dist//`) or `resourcesOutputPath`.
- See the documentation for `ng build` for more information about these options.
+- `index.html`
+- `favicon.ico`
+- Build artifacts (JS and CSS bundles)
+- Anything under `assets`
+- Images and fonts directly under the configured `outputPath` (by default `./dist//`) or `resourcesOutputPath`.
+ See the documentation for `ng build` for more information about these options.
IMPORTANT: The generated `ngsw-config.json` includes a limited list of cacheable fonts and images extensions. In some cases, you might want to modify the glob pattern to suit your needs.
@@ -114,50 +114,48 @@ Now that you've seen how service workers cache your application, the next step i
Make a change to the application, and watch the service worker install the update:
1. If you're testing in an incognito window, open a second blank tab.
- This keeps the incognito and the cache state alive during your test.
+ This keeps the incognito and the cache state alive during your test.
1. Close the application tab, but not the window.
- This should also close the Developer Tools.
+ This should also close the Developer Tools.
1. Shut down `http-server` (Ctrl-c).
1. Open `src/app/app.component.html` for editing.
1. Change the text `Welcome to {{title}}!` to `Bienvenue à {{title}}!`.
1. Build and run the server again:
-
-
+```shell
ng build
npx http-server -p 8080 -c-1 dist//browser
-
-
+```
### Updating your application in the browser
Now look at how the browser and service worker handle the updated application.
1. Open [http://localhost:8080](http://localhost:8080) again in the same window.
- What happens?
+ What happens?
-
+
- What went wrong?
- _Nothing, actually!_
- The Angular service worker is doing its job and serving the version of the application that it has **installed**, even though there is an update available.
- In the interest of speed, the service worker doesn't wait to check for updates before it serves the application that it has cached.
+ What went wrong?
+ _Nothing, actually!_
+ The Angular service worker is doing its job and serving the version of the application that it has **installed**, even though there is an update available.
+ In the interest of speed, the service worker doesn't wait to check for updates before it serves the application that it has cached.
- Look at the `http-server` logs to see the service worker requesting `/ngsw.json`.
+ Look at the `http-server` logs to see the service worker requesting `/ngsw.json`.
-
- [2023-09-07T00:37:24.372Z] "GET /ngsw.json?ngsw-cache-bust=0.9365263935102124" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
-
+ ```text
+ [2023-09-07T00:37:24.372Z] "GET /ngsw.json?ngsw-cache-bust=0.9365263935102124" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
+ ```
- This is how the service worker checks for updates.
+ This is how the service worker checks for updates.
1. Refresh the page.
-
+
- The service worker installed the updated version of your application _in the background_, and the next time the page is loaded or reloaded, the service worker switches to the latest version.
+ The service worker installed the updated version of your application _in the background_, and the next time the page is loaded or reloaded, the service worker switches to the latest version.
## Service worker configuration
@@ -167,7 +165,7 @@ Angular service workers support comprehensive configuration options through the
The `enabled` option controls whether the service worker will be registered and related services will attempt to communicate with it.
-
+```ts
import { ApplicationConfig, isDevMode } from '@angular/core';
import { provideServiceWorker } from '@angular/service-worker';
@@ -180,14 +178,13 @@ export const appConfig: ApplicationConfig = {
],
};
-
-
+```
### Cache control with updateViaCache
The `updateViaCache` option controls how the browser consults the HTTP cache during service worker updates. This provides fine-grained control over when the browser fetches updated service worker scripts and imported modules.
-
+```ts
export const appConfig: ApplicationConfig = {
providers: [
@@ -198,19 +195,19 @@ export const appConfig: ApplicationConfig = {
],
};
-
+```
The `updateViaCache` option accepts the following values:
-* **`'imports'`** - The HTTP cache is consulted for the service worker script's imported scripts, but not for the service worker script itself
-* **`'all'`** - The HTTP cache is consulted for both the service worker script and its imported scripts
-* **`'none'`** - The HTTP cache is not consulted for the service worker script or its imported scripts
+- **`'imports'`** - The HTTP cache is consulted for the service worker script's imported scripts, but not for the service worker script itself
+- **`'all'`** - The HTTP cache is consulted for both the service worker script and its imported scripts
+- **`'none'`** - The HTTP cache is not consulted for the service worker script or its imported scripts
### ES Module support with type option
The `type` option enables specifying the script type when registering service workers, providing support for ES module features in your service worker scripts.
-
+```ts
export const appConfig: ApplicationConfig = {
providers: [
@@ -221,18 +218,18 @@ export const appConfig: ApplicationConfig = {
],
};
-
+```
The `type` option accepts the following values:
-* **`'classic'`** (default) - Traditional service worker script execution. ES module features such as `import` and `export` are NOT allowed in the script
-* **`'module'`** - Registers the script as an ES module. Allows use of `import`/`export` syntax and module features
+- **`'classic'`** (default) - Traditional service worker script execution. ES module features such as `import` and `export` are NOT allowed in the script
+- **`'module'`** - Registers the script as an ES module. Allows use of `import`/`export` syntax and module features
### Registration scope control
The `scope` option defines the service worker's registration scope, determining what range of URLs it can control.
-
+```ts
export const appConfig: ApplicationConfig = {
providers: [
@@ -243,17 +240,17 @@ export const appConfig: ApplicationConfig = {
],
};
-
+```
-* Controls which URLs the service worker can intercept and manage
-* By default, the scope is the directory containing the service worker script
-* Used when calling `ServiceWorkerContainer.register()`
+- Controls which URLs the service worker can intercept and manage
+- By default, the scope is the directory containing the service worker script
+- Used when calling `ServiceWorkerContainer.register()`
### Registration strategy configuration
The `registrationStrategy` option defines when the service worker will be registered with the browser, providing control over the timing of registration.
-
+```ts
export const appConfig: ApplicationConfig = {
providers: [
@@ -264,15 +261,15 @@ export const appConfig: ApplicationConfig = {
],
};
-
+```
Available registration strategies:
-* **`'registerWhenStable:timeout'`** (default: `'registerWhenStable:30000'`) - Register as soon as the application stabilizes (no pending micro-/macro-tasks) but no later than the specified timeout in milliseconds
-* **`'registerImmediately'`** - Register the service worker immediately
-* **`'registerWithDelay:timeout'`** - Register with a delay of the specified timeout in milliseconds
+- **`'registerWhenStable:timeout'`** (default: `'registerWhenStable:30000'`) - Register as soon as the application stabilizes (no pending micro-/macro-tasks) but no later than the specified timeout in milliseconds
+- **`'registerImmediately'`** - Register the service worker immediately
+- **`'registerWithDelay:timeout'`** - Register with a delay of the specified timeout in milliseconds
-
+```ts
// Register immediately
export const immediateConfig: ApplicationConfig = {
@@ -294,11 +291,11 @@ export const delayedConfig: ApplicationConfig = {
],
};
-
+```
You can also provide an Observable factory function for custom registration timing:
-
+```ts
import { timer } from 'rxjs';
export const customConfig: ApplicationConfig = {
@@ -310,7 +307,7 @@ export const customConfig: ApplicationConfig = {
],
};
-
+```
## More on Angular service workers
diff --git a/adev-ja/src/content/ecosystem/service-workers/overview.md b/adev-ja/src/content/ecosystem/service-workers/overview.md
index 6e0fe6e078..dc80edeb79 100644
--- a/adev-ja/src/content/ecosystem/service-workers/overview.md
+++ b/adev-ja/src/content/ecosystem/service-workers/overview.md
@@ -15,7 +15,7 @@ Service worker-based caching is thus completely programmable and doesn't rely on
Unlike the other scripts that make up an application, such as the Angular application bundle, the service worker is preserved after the user closes the tab.
The next time that browser loads the application, the service worker loads first, and can intercept every request for resources to load the application.
-If the service worker is designed to do so, it can *completely satisfy the loading of the application, without the need for the network*.
+If the service worker is designed to do so, it can _completely satisfy the loading of the application, without the need for the network_.
Even across a fast reliable network, round-trip delays can introduce significant latency when loading the application.
Using a service worker to reduce dependency on the network can significantly improve the user experience.
@@ -28,22 +28,22 @@ Angular's service worker is designed to optimize the end user experience of usin
To achieve this, the Angular service worker follows these guidelines:
-* Caching an application is like installing a native application.
- The application is cached as one unit, and all files update together.
+- Caching an application is like installing a native application.
+ The application is cached as one unit, and all files update together.
-* A running application continues to run with the same version of all files.
- It does not suddenly start receiving cached files from a newer version, which are likely incompatible.
+- A running application continues to run with the same version of all files.
+ It does not suddenly start receiving cached files from a newer version, which are likely incompatible.
-* When users refresh the application, they see the latest fully cached version.
- New tabs load the latest cached code.
+- When users refresh the application, they see the latest fully cached version.
+ New tabs load the latest cached code.
-* Updates happen in the background, relatively quickly after changes are published.
- The previous version of the application is served until an update is installed and ready.
+- Updates happen in the background, relatively quickly after changes are published.
+ The previous version of the application is served until an update is installed and ready.
-* The service worker conserves bandwidth when possible.
- Resources are only downloaded if they've changed.
+- The service worker conserves bandwidth when possible.
+ Resources are only downloaded if they've changed.
-To support these behaviors, the Angular service worker loads a *manifest* file from the server.
+To support these behaviors, the Angular service worker loads a _manifest_ file from the server.
The file, called `ngsw.json` (not to be confused with the [web app manifest](https://developer.mozilla.org/docs/Web/Manifest)), describes the resources to cache and includes hashes of every file's contents.
When an update to the application is deployed, the contents of the manifest change, informing the service worker that a new version of the application should be downloaded and cached.
This manifest is generated from a CLI-generated configuration file called `ngsw-config.json`.
@@ -60,7 +60,7 @@ For service workers to be registered, the application must be accessed over HTTP
Browsers ignore service workers on pages that are served over an insecure connection.
The reason is that service workers are quite powerful, so extra care is needed to ensure the service worker script has not been tampered with.
-There is one exception to this rule: to make local development more straightforward, browsers do *not* require a secure connection when accessing an application on `localhost`.
+There is one exception to this rule: to make local development more straightforward, browsers do _not_ require a secure connection when accessing an application on `localhost`.
### Browser support
@@ -71,9 +71,9 @@ Browsers like IE and Opera Mini do not support service workers.
If the user is accessing your application with a browser that does not support service workers, the service worker is not registered and related behavior such as offline cache management and push notifications does not happen.
More specifically:
-* The browser does not download the service worker script and the `ngsw.json` manifest file
-* Active attempts to interact with the service worker, such as calling `SwUpdate.checkForUpdate()`, return rejected promises
-* The observable events of related services, such as `SwUpdate.available`, are not triggered
+- The browser does not download the service worker script and the `ngsw.json` manifest file
+- Active attempts to interact with the service worker, such as calling `SwUpdate.checkForUpdate()`, return rejected promises
+- The observable events of related services, such as `SwUpdate.available`, are not triggered
It is highly recommended that you ensure that your application works even without service worker support in the browser.
Although an unsupported browser ignores service worker caching, it still reports errors if the application attempts to interact with the service worker.
diff --git a/adev-ja/src/content/ecosystem/service-workers/push-notifications.md b/adev-ja/src/content/ecosystem/service-workers/push-notifications.md
index 2f1ac6a63d..054b95826a 100644
--- a/adev-ja/src/content/ecosystem/service-workers/push-notifications.md
+++ b/adev-ja/src/content/ecosystem/service-workers/push-notifications.md
@@ -23,8 +23,7 @@ The default behavior for the `notificationclick` event is to close the notificat
You can specify an additional operation to be executed on `notificationclick` by adding an `onActionClick` property to the `data` object, and providing a `default` entry.
This is especially useful for when there are no open clients when a notification is clicked.
-
-
+```json
{
"notification": {
"title": "New Notification!",
@@ -35,19 +34,18 @@ This is especially useful for when there are no open clients when a notification
}
}
}
-
-
+```
### Operations
The Angular service worker supports the following operations:
-| Operations | Details |
-|:--- |:--- |
+| Operations | Details |
+| :-------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| `openWindow` | Opens a new tab at the specified URL. |
| `focusLastFocusedOrOpen` | Focuses the last focused client. If there is no client open, then it opens a new tab at the specified URL. |
| `navigateLastFocusedOrOpen` | Focuses the last focused client and navigates it to the specified URL. If there is no client open, then it opens a new tab at the specified URL. |
-| `sendRequest` | Send a simple GET request to the specified URL. |
+| `sendRequest` | Send a simple GET request to the specified URL. |
IMPORTANT: URLs are resolved relative to the service worker's registration scope. If an `onActionClick` item does not define a `url`, then the service worker's registration scope is used.
@@ -60,8 +58,7 @@ Each action is represented as an action button that the user can click to intera
In addition, using the `onActionClick` property on the `data` object, you can tie each action to an operation to be performed when the corresponding action button is clicked:
-
-
+```json
{
"notification": {
"title": "New Notification!",
@@ -83,8 +80,7 @@ In addition, using the `onActionClick` property on the `data` object, you can ti
}
}
}
-
-
+```
IMPORTANT: If an action does not have a corresponding `onActionClick` entry, then the notification is closed and `SwPush.notificationClicks` is notified on existing clients.
@@ -93,7 +89,6 @@ IMPORTANT: If an action does not have a corresponding `onActionClick` entry, the
You might also be interested in the following:
-
diff --git a/adev-ja/src/content/ecosystem/web-workers.md b/adev-ja/src/content/ecosystem/web-workers.md
index c832564b4e..9ebd9fcdcd 100644
--- a/adev-ja/src/content/ecosystem/web-workers.md
+++ b/adev-ja/src/content/ecosystem/web-workers.md
@@ -9,52 +9,47 @@ HELPFUL: The Angular CLI does not support running itself in a web worker.
To add a web worker to an existing project, use the Angular CLI `ng generate` command.
-
-
+```shell
ng generate web-worker
-
-
+```
You can add a web worker anywhere in your application.
For example, to add a web worker to the root component, `src/app/app.component.ts`, run the following command.
-
-
+```shell
ng generate web-worker app
-
-
+```
The command performs the following actions.
1. Configures your project to use web workers, if it isn't already.
-1. Adds the following scaffold code to `src/app/app.worker.ts` to receive messages.
+1. Adds the following scaffold code to `src/app/app.worker.ts` to receive messages.
-
+ ```ts {header:"src/app/app.worker.ts"}
- addEventListener('message', ({ data }) => {
- const response = `worker response to ${data}`;
- postMessage(response);
- });
+ addEventListener('message', ({ data }) => {
+ const response = `worker response to ${data}`;
+ postMessage(response);
+ });
-
+ ```
1. Adds the following scaffold code to `src/app/app.component.ts` to use the worker.
-
-
- if (typeof Worker !== 'undefined') {
- // Create a new
- const worker = new Worker(new URL('./app.worker', import.meta.url));
- worker.onmessage = ({ data }) => {
- console.log(`page got message: ${data}`);
- };
- worker.postMessage('hello');
- } else {
- // Web workers are not supported in this environment.
- // You should add a fallback so that your program still executes correctly.
- }
-
-
+ ```ts {header:"src/app/app.component.ts"}
+
+ if (typeof Worker !== 'undefined') {
+ // Create a new
+ const worker = new Worker(new URL('./app.worker', import.meta.url));
+ worker.onmessage = ({ data }) => {
+ console.log(`page got message: ${data}`);
+ };
+ worker.postMessage('hello');
+ } else {
+ // Web workers are not supported in this environment.
+ // You should add a fallback so that your program still executes correctly.
+ }
+ ```
After you create this initial scaffold, you must refactor your code to use the web worker by sending messages to and from the worker.
diff --git a/adev-ja/src/content/events/v21.md b/adev-ja/src/content/events/v21.md
new file mode 100644
index 0000000000..856de18a0f
--- /dev/null
+++ b/adev-ja/src/content/events/v21.md
@@ -0,0 +1,27 @@
+
+
+# Angular v21: The Adventure Begins
+
+## Save the Date November 20, 2025
+
+
+
+
+
+
+
+
+Join the Angular team this November for a brand new release adventure. With modern AI tooling, performance updates and more, Angular v21 delivers fantastic new features to improve your developer experience. Whether you’re creating AI-powered apps or scalable enterprise applications, there has never been a better time to build with Angular.
+
+🔥 What's coming in v21
+
+- New Angular MCP Server tools to improve AI-powered workflows and code generation
+- Your first look at Signal Forms, our new streamlined, signal-based approach to forms in Angular
+- Exciting new details about the Angular ARIA package
+
+That’s just a taste of what’s coming in our upcoming major release event. You won't want to miss it.
+
+
+
+
+
diff --git a/adev-ja/src/content/examples/i18n/readme.md b/adev-ja/src/content/examples/i18n/readme.md
index c01dfd111a..a724b587a4 100644
--- a/adev-ja/src/content/examples/i18n/readme.md
+++ b/adev-ja/src/content/examples/i18n/readme.md
@@ -8,7 +8,7 @@ This sample comes from the Angular documentation's "[Example Angular Internation
2. `npm start` to see it run in English
3. `npm run start:fr` to see it run with French translation.
->See the scripts in `package.json` for an explanation of these commands.
+> See the scripts in `package.json` for an explanation of these commands.
## Run in Stackblitz
diff --git a/adev-ja/src/content/guide/animations/complex-sequences.md b/adev-ja/src/content/guide/animations/complex-sequences.md
index 4eb1da6869..27a69f3879 100644
--- a/adev-ja/src/content/guide/animations/complex-sequences.md
+++ b/adev-ja/src/content/guide/animations/complex-sequences.md
@@ -8,26 +8,26 @@ You can choose to run multiple animations in parallel, or run discrete animation
The functions that control complex animation sequences are:
-| Functions | Details |
-|:--- |:--- |
-| `query()` | Finds one or more inner HTML elements. |
+| Functions | Details |
+| :-------------------------------- | :------------------------------------------------------------- |
+| `query()` | Finds one or more inner HTML elements. |
| `stagger()` | Applies a cascading delay to animations for multiple elements. |
-| [`group()`](api/animations/group) | Runs multiple animation steps in parallel. |
-| `sequence()` | Runs animation steps one after another. |
+| [`group()`](api/animations/group) | Runs multiple animation steps in parallel. |
+| `sequence()` | Runs animation steps one after another. |
## The query() function
Most complex animations rely on the `query()` function to find child elements and apply animations to them, basic examples of such are:
-| Examples | Details |
-|:--- |:--- |
-| `query()` followed by `animate()` | Used to query simple HTML elements and directly apply animations to them. |
+| Examples | Details |
+| :------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `query()` followed by `animate()` | Used to query simple HTML elements and directly apply animations to them. |
| `query()` followed by `animateChild()` | Used to query child elements, which themselves have animations metadata applied to them and trigger such animation \(which would be otherwise be blocked by the current/parent element's animation\). |
The first argument of `query()` is a [css selector](https://developer.mozilla.org/docs/Web/CSS/CSS_Selectors) string which can also contain the following Angular-specific tokens:
-| Tokens | Details |
-|:--- |:--- |
+| Tokens | Details |
+| :------------------------- | :------------------------------------------- |
| `:enter` `:leave` | For entering/leaving elements. |
| `:animating` | For elements currently animating. |
| `@*` `@triggerName` | For elements with any—or a specific—trigger. |
@@ -47,14 +47,14 @@ After having queried child elements via `query()`, the `stagger()` function lets
The following example demonstrates how to use the `query()` and `stagger()` functions to animate a list \(of heroes\) adding each in sequence, with a slight delay, from top to bottom.
-* Use `query()` to look for an element entering the page that meets certain criteria
-* For each of these elements, use `style()` to set the same initial style for the element.
- Make it transparent and use `transform` to move it out of position so that it can slide into place.
+- Use `query()` to look for an element entering the page that meets certain criteria
+- For each of these elements, use `style()` to set the same initial style for the element.
+ Make it transparent and use `transform` to move it out of position so that it can slide into place.
-* Use `stagger()` to delay each animation by 30 milliseconds
-* Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it
+- Use `stagger()` to delay each animation by 30 milliseconds
+- Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it
-
+
## Parallel animation using group() function
@@ -63,11 +63,11 @@ But you might also want to configure animations that happen in parallel.
For example, you might want to animate two CSS properties of the same element but use a different `easing` function for each one.
For this, you can use the animation [`group()`](api/animations/group) function.
-HELPFUL: The [`group()`](api/animations/group) function is used to group animation *steps*, rather than animated elements.
+HELPFUL: The [`group()`](api/animations/group) function is used to group animation _steps_, rather than animated elements.
The following example uses [`group()`](api/animations/group)s on both `:enter` and `:leave` for two different timing configurations, thus applying two independent animations to the same element in parallel.
-
+
## Sequential vs. parallel animations
@@ -77,8 +77,8 @@ But what if you want to create an animation involving several animations happeni
A second function called `sequence()` lets you run those same animations one after the other.
Within `sequence()`, the animation steps consist of either `style()` or `animate()` function calls.
-* Use `style()` to apply the provided styling data immediately.
-* Use `animate()` to apply styling data over a given time interval.
+- Use `style()` to apply the provided styling data immediately.
+- Use `animate()` to apply styling data over a given time interval.
## Filter animation example
@@ -91,24 +91,24 @@ The heroes list gradually re-enters the page as you delete each letter in the fi
The HTML template contains a trigger called `filterAnimation`.
-
+
The `filterAnimation` in the component's decorator contains three transitions.
-
+
The code in this example performs the following tasks:
-* Skips animations when the user first opens or navigates to this page \(the filter animation narrows what is already there, so it only works on elements that already exist in the DOM\)
-* Filters heroes based on the search input's value
+- Skips animations when the user first opens or navigates to this page \(the filter animation narrows what is already there, so it only works on elements that already exist in the DOM\)
+- Filters heroes based on the search input's value
For each change:
-* Hides an element leaving the DOM by setting its opacity and width to 0
-* Animates an element entering the DOM over 300 milliseconds.
- During the animation, the element assumes its default width and opacity.
+- Hides an element leaving the DOM by setting its opacity and width to 0
+- Animates an element entering the DOM over 300 milliseconds.
+ During the animation, the element assumes its default width and opacity.
-* If there are multiple elements entering or leaving the DOM, staggers each animation starting at the top of the page, with a 50-millisecond delay between each element
+- If there are multiple elements entering or leaving the DOM, staggers each animation starting at the top of the page, with a 50-millisecond delay between each element
## Animating the items of a reordering list
@@ -121,11 +121,11 @@ IMPORTANT: If you need to animate the items of an `*ngFor` list and there is a p
## Animations and Component View Encapsulation
-Angular animations are based on the components DOM structure and do not directly take [View Encapsulation](guide/components/styling#style-scoping) into account, this means that components using `ViewEncapsulation.Emulated` behave exactly as if they were using `ViewEncapsulation.None` (`ViewEncapsulation.ShadowDom` behaves differently as we'll discuss shortly).
+Angular animations are based on the components DOM structure and do not directly take [View Encapsulation](guide/components/styling#style-scoping) into account, this means that components using `ViewEncapsulation.Emulated` behave exactly as if they were using `ViewEncapsulation.None` (`ViewEncapsulation.ShadowDom` and `ViewEncapsulation.ExperimentalIsolatedShadowDom` behave differently as we'll discuss shortly).
For example if the `query()` function (which you'll see more of in the rest of the Animations guide) were to be applied at the top of a tree of components using the emulated view encapsulation, such query would be able to identify (and thus animate) DOM elements on any depth of the tree.
-On the other hand the `ViewEncapsulation.ShadowDom` changes the component's DOM structure by "hiding" DOM elements inside [`ShadowRoot`](https://developer.mozilla.org/docs/Web/API/ShadowRoot) elements. Such DOM manipulations do prevent some of the animations implementation to work properly since it relies on simple DOM structures and doesn't take `ShadowRoot` elements into account. Therefore it is advised to avoid applying animations to views incorporating components using the ShadowDom view encapsulation.
+On the other hand the `ViewEncapsulation.ShadowDom` and `ViewEncapsulation.ExperimentalIsolatedShadowDom` changes the component's DOM structure by "hiding" DOM elements inside [`ShadowRoot`](https://developer.mozilla.org/docs/Web/API/ShadowRoot) elements. Such DOM manipulations do prevent some of the animations implementation to work properly since it relies on simple DOM structures and doesn't take `ShadowRoot` elements into account. Therefore it is advised to avoid applying animations to views incorporating components using the ShadowDom view encapsulation.
## Animation sequence summary
diff --git a/adev-ja/src/content/guide/animations/css.md b/adev-ja/src/content/guide/animations/css.md
index b91b3743d4..0e68cf2540 100644
--- a/adev-ja/src/content/guide/animations/css.md
+++ b/adev-ja/src/content/guide/animations/css.md
@@ -4,14 +4,14 @@ CSS offers a robust set of tools for you to create beautiful and engaging animat
## How to write animations in native CSS
-If you've never written any native CSS animations, there are a number of excellent guides to get you started. Here's a few of them:
-[MDN's CSS Animations guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations/Using_CSS_animations)
-[W3Schools CSS3 Animations guide](https://www.w3schools.com/css/css3_animations.asp)
-[The Complete CSS Animations Tutorial](https://www.lambdatest.com/blog/css-animations-tutorial/)
-[CSS Animation for Beginners](https://thoughtbot.com/blog/css-animation-for-beginners)
-
-and a couple of videos:
-[Learn CSS Animation in 9 Minutes](https://www.youtube.com/watch?v=z2LQYsZhsFw)
+If you've never written any native CSS animations, there are a number of excellent guides to get you started. Here's a few of them:
+[MDN's CSS Animations guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations/Using_CSS_animations)
+[W3Schools CSS3 Animations guide](https://www.w3schools.com/css/css3_animations.asp)
+[The Complete CSS Animations Tutorial](https://www.lambdatest.com/blog/css-animations-tutorial/)
+[CSS Animation for Beginners](https://thoughtbot.com/blog/css-animation-for-beginners)
+
+and a couple of videos:
+[Learn CSS Animation in 9 Minutes](https://www.youtube.com/watch?v=z2LQYsZhsFw)
[Net Ninja CSS Animation Tutorial Playlist](https://www.youtube.com/watch?v=jgw82b5Y2MU&list=PL4cUxeGkcC9iGYgmEd2dm3zAKzyCGDtM5)
Check some of these various guides and tutorials out, and then come back to this guide.
@@ -20,7 +20,7 @@ Check some of these various guides and tutorials out, and then come back to this
You can create reusable animations that can be shared across your application using `@keyframes`. Define keyframe animations in a shared CSS file, and you'll be able to re-use those keyframe animations wherever you want within your application.
-
+
Adding the class `animated-class` to an element would trigger the animation on that element.
@@ -30,7 +30,7 @@ Adding the class `animated-class` to an element would trigger the animation on t
You may want to animate between two different states, for example when an element is opened or closed. You can accomplish this by using CSS classes either using a keyframe animation or transition styling.
-
+
Triggering the `open` or `closed` state is done by toggling classes on the element in your component. You can find examples of how to do this in our [template guide](guide/templates/binding#css-class-and-style-property-bindings).
@@ -42,20 +42,20 @@ Animating often requires adjusting timing, delays and easeing behaviors. This ca
Specify `animation-duration`, `animation-delay`, and `animation-timing-function` for a keyframe animation in CSS, or alternatively use the `animation` shorthand property.
-
+
Similarly, you can use `transition-duration`, `transition-delay`, and `transition-timing-function` and the `transition` shorthand for animations that are not using `@keyframes`.
-
+
### Triggering an Animation
Animations can be triggered by toggling CSS styles or classes. Once a class is present on an element, the animation will occur. Removing the class will revert the element back to whatever CSS is defined for that element. Here's an example:
-
-
-
+
+
+
## Transition and Triggers
@@ -65,9 +65,9 @@ Animations can be triggered by toggling CSS styles or classes. Once a class is p
You can use css-grid to animate to auto height.
-
-
-
+
+
+
If you don't have to worry about supporting all browsers, you can also check out `calc-size()`, which is the true solution to animating auto height. See [MDN's docs](https://developer.mozilla.org/en-US/docs/Web/CSS/calc-size) and (this tutorial)[https://frontendmasters.com/blog/one-of-the-boss-battles-of-css-is-almost-won-transitioning-to-auto/] for more information.
@@ -77,17 +77,17 @@ If you don't have to worry about supporting all browsers, you can also check out
You can create animations for when an item enters a view or leaves a view. Let's start by looking at how to animate an element entering a view. We'll do this with `animate.enter`, which will apply animation classes when an element enters the view.
-
-
-
+
+
+
Animating an element when it leaves the view is similar to animating when entering a view. Use `animate.leave` to specify which CSS classes to apply when the element leaves the view.
-
-
-
+
+
+
For more information on `animate.enter` and `animate.leave`, see the [Enter and Leave animations guide](guide/animations).
@@ -97,9 +97,9 @@ For more information on `animate.enter` and `animate.leave`, see the [Enter and
Animating on increment and decrement is a common pattern in applications. Here's an example of how you can accomplish that behavior.
-
-
-
+
+
+
### Disabling an animation or all animations
@@ -128,12 +128,12 @@ If you have actions you would like to execute at certain points during animation
[`OnAnimationStart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationstart_event)
[`OnAnimationEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationend_event)
[`OnAnimationIteration`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationitration_event)
-[`OnAnimationCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event)
+[`OnAnimationCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event)
[`OnTransitionStart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionstart_event)
[`OnTransitionRun`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionrun_event)
[`OnTransitionEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionend_event)
-[`OnTransitionCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitioncancel_event)
+[`OnTransitionCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitioncancel_event)
The Web Animations API has a lot of additional functionality. [Take a look at the documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) to see all the available animation APIs.
@@ -148,9 +148,9 @@ Animations are often more complicated than just a simple fade in or fade out. Yo
One common effect is to stagger the animations of each item in a list to create a cascade effect. This can be accomplished by utilizing `animation-delay` or `transition-delay`. Here is an example of what that CSS might look like.
-
-
-
+
+
+
### Parallel Animations
@@ -167,12 +167,12 @@ In this example, the `rotate` and `fade-in` animations fire at the same time, bu
### Animating the items of a reordering list
-Items in a `@for` loop will be removed and re-added, which will fire off animations using `@starting-styles` for entry animations. Alternatively, you can use `animate.enter` for this same behavior. Use `animate.leave` to animate elements as they are removed, as seen in the example above.
+Items in a `@for` loop will be removed and re-added, which will fire off animations using `@starting-styles` for entry animations. Alternatively, you can use `animate.enter` for this same behavior. Use `animate.leave` to animate elements as they are removed, as seen in the example below.
-
-
-
+
+
+
## Programmatic control of animations
diff --git a/adev-ja/src/content/guide/animations/enter-and-leave.en.md b/adev-ja/src/content/guide/animations/enter-and-leave.en.md
index 5059af9c29..8ab48087de 100644
--- a/adev-ja/src/content/guide/animations/enter-and-leave.en.md
+++ b/adev-ja/src/content/guide/animations/enter-and-leave.en.md
@@ -3,9 +3,9 @@
Well-designed animations can make your application more fun and straightforward to use, but they aren't just cosmetic.
Animations can improve your application and user experience in a number of ways:
-* Without animations, web page transitions can seem abrupt and jarring
-* Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions
-* Good animations can smoothly direct the user's attention throughout a workflow
+- Without animations, web page transitions can seem abrupt and jarring
+- Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions
+- Good animations can smoothly direct the user's attention throughout a workflow
Angular provides `animate.enter` and `animate.leave` to animate your application's elements. These two features apply enter and leave CSS classes at the appropriate times or call functions to apply animations from third party libraries. `animate.enter` and `animate.leave` are not directives. They are special API supported directly by the Angular compiler. They can be used on elements directly and can also be used as a host binding.
@@ -14,9 +14,9 @@ Angular provides `animate.enter` and `animate.leave` to animate your application
You can use `animate.enter` to animate elements as they _enter_ the DOM. You can define enter animations using CSS classes with either transitions or keyframe animations.
-
-
-
+
+
+
When the animation completes, Angular removes the class or classes that you specified in `animate.enter` from the DOM. Animation classes are only be present while the animation is active.
@@ -28,9 +28,9 @@ You can use `animate.enter` with any other Angular features, such as control flo
A quick note about using CSS transitions: If you choose to use transitions instead of keyframe animations, the classes added to the element with `animate.enter` represent the state that the transition will animate _to_. Your base element CSS is what the element will look like when no animations run, which is likely similar to the end state of the CSS transition. So you would still need to pair it with `@starting-style` to have an appropriate _from_ state for your transition to work.
-
-
-
+
+
+
## `animate.leave`
@@ -38,9 +38,9 @@ A quick note about using CSS transitions: If you choose to use transitions inste
You can use `animate.leave` to animate elements as they _leave_ the DOM. You can define leave animations using CSS classes with either transforms or keyframe animations.
-
-
-
+
+
+
When the animation completes, Angular automatically removes the animated element from the DOM.
@@ -50,9 +50,9 @@ NOTE: When using multiple keyframe animations or transition properties on a an e
`animate.leave` can also be used with signals, and other bindings. You can use `animate.leave` with a single class or multiple classes. Either specify it as a simple string with spaces or a string array.
-
-
-
+
+
+
## Event Bindings, Functions, and Third-party Libraries
@@ -60,9 +60,9 @@ NOTE: When using multiple keyframe animations or transition properties on a an e
Both `animate.enter` and `animate.leave` support event binding syntax that allows for function calls. You can use this syntax to call a function in your component code or utilize third-party animation libraries, like [GSAP](https://gsap.com/), [anime.js](https://animejs.com/), or any other JavaScript animation library.
-
-
-
+
+
+
The `$event` object has the type `AnimationCallbackEvent`. It includes the element as the `target` and provides an `animationComplete()` function to notify the framework when the animation finishes.
@@ -75,6 +75,10 @@ If you don't call `animationComplete()` when using `animate.leave`, Angular call
{ provide: MAX_ANIMATION_TIMEOUT, useValue: 6000 }
```
+## Compatibility with Legacy Angular Animations
+
+You cannot use legacy animations alongside `animate.enter` and `animate.leave` within the same component. Doing so would result in enter classes remaining on the element or leaving nodes not being removed. It is otherwise fine to use both legacy animations and the new `animate.enter` and `animate.leave` animations within the same _application_. The only caveat is content projection. If you are projecting content from one component with legacy animations into another component with `animate.enter` or `animate.leave`, or vice versa, this will result in the same behavior as if they are used together in the same component. This is not supported.
+
## Testing
TestBed provides built-in support for enabling or disabling animations in your test environment. CSS animations require a browser to run, and many of the APIs are not available in a test environment. By default, TestBed disables animations for you in your test environments.
diff --git a/adev-ja/src/content/guide/animations/enter-and-leave.md b/adev-ja/src/content/guide/animations/enter-and-leave.md
index a7432f3c05..fd08e4f892 100644
--- a/adev-ja/src/content/guide/animations/enter-and-leave.md
+++ b/adev-ja/src/content/guide/animations/enter-and-leave.md
@@ -3,9 +3,9 @@
適切に設計されたアニメーションは、アプリケーションをより楽しく、分かりやすく使用できるようにしますが、単なる装飾ではありません。
アニメーションは、いくつかの方法でアプリケーションとユーザー体験を向上させることができます。
-* アニメーションがないと、ウェブページの遷移は突然で不快に感じられることがあります
-* モーションはユーザー体験を大幅に向上させるため、アニメーションはユーザーが自分のアクションに対するアプリケーションの応答を検出する機会を与えます
-* 優れたアニメーションは、ワークフロー全体でユーザーの注意をスムーズに誘導できます
+- アニメーションがないと、ウェブページの遷移は突然で不快に感じられることがあります
+- モーションはユーザー体験を大幅に向上させるため、アニメーションはユーザーが自分のアクションに対するアプリケーションの応答を検出する機会を与えます
+- 優れたアニメーションは、ワークフロー全体でユーザーの注意をスムーズに誘導できます
Angularは、アプリケーションの要素をアニメーション化するために`animate.enter`と`animate.leave`を提供します。これら2つの機能は、適切なタイミングでenterおよびleaveのCSSクラスを適用するか、サードパーティライブラリからアニメーションを適用する関数を呼び出します。`animate.enter`と`animate.leave`はディレクティブではありません。これらはAngularコンパイラによって直接サポートされる特別なAPIです。これらは要素に直接使用できるほか、ホストバインディングとしても使用できます。
@@ -14,9 +14,9 @@ Angularは、アプリケーションの要素をアニメーション化する
`animate.enter`はDOMに_入る_要素をアニメーション化するために使用できます。CSSクラスと、transitionまたはキーフレームアニメーションのいずれかを使用して、enterアニメーションを定義できます。
-
-
-
+
+
+
アニメーションが完了すると、Angularは`animate.enter`で指定したクラスをDOMから削除します。アニメーションクラスは、アニメーションがアクティブな間のみ存在します。
@@ -28,9 +28,9 @@ NOTE: 要素で複数のキーフレームアニメーションまたはtransiti
CSSトランジションの使用についての簡単な注意:キーフレームアニメーションの代わりにトランジションを使用することを選択した場合、`animate.enter`で要素に追加されるクラスは、トランジションがアニメーション_する先の_状態を表します。基本要素のCSSは、アニメーションが実行されないときの要素の外観であり、CSSトランジションの終了状態に似ている可能性があります。そのため、トランジションが機能するために適切な_from_状態を持つために、`@starting-style`と組み合わせる必要があります。
-
-
-
+
+
+
## `animate.leave`
@@ -38,9 +38,9 @@ CSSトランジションの使用についての簡単な注意:キーフレ
`animate.leave` を使用して、要素がDOMから_離れる_ときにアニメーションを適用できます。CSSクラスと、transformまたはキーフレームアニメーションのいずれかを使用して、離脱アニメーションを定義できます。
-
-
-
+
+
+
アニメーションが完了すると、Angularはアニメーション化された要素をDOMから自動的に削除します。
@@ -50,9 +50,9 @@ NOTE: 要素に複数のキーフレームアニメーションまたはtransiti
`animate.leave` はsignalsやその他のbindingでも使用できます。`animate.leave` は単一のクラスまたは複数のクラスで使用できます。スペースで区切られた単純な文字列として指定するか、文字列配列として指定します。
-
-
-
+
+
+
## イベントバインディング、関数、およびサードパーティライブラリ {#event-bindings-functions-and-third-party-libraries}
@@ -60,9 +60,9 @@ NOTE: 要素に複数のキーフレームアニメーションまたはtransiti
`animate.enter`と`animate.leave`はどちらも、関数呼び出しを可能にするイベントバインディング構文をサポートしています。この構文を使用して、コンポーネントコード内の関数を呼び出したり、[GSAP](https://gsap.com/)、[anime.js](https://animejs.com/)などのサードパーティのアニメーションライブラリ、またはその他のJavaScriptアニメーションライブラリを利用したり可能です。
-
-
-
+
+
+
`$event`オブジェクトは`AnimationCallbackEvent`型です。これには`target`として要素が含まれ、アニメーションが終了したときにフレームワークに通知するための`animationComplete()`関数を提供します。
@@ -75,6 +75,10 @@ IMPORTANT: Angularが要素を削除するためには、`animate.leave`を使
{ provide: MAX_ANIMATION_TIMEOUT, useValue: 6000 }
```
+## レガシーAngularアニメーションとの互換性 {#compatibility-with-legacy-angular-animations}
+
+同じコンポーネント内でレガシーアニメーションと`animate.enter`および`animate.leave`を一緒に使用できません。そうすると、enterクラスが要素に残ったり、leavingノードが削除されなかったりします。それ以外では、同じ_アプリケーション_内でレガシーアニメーションと新しい`animate.enter`および`animate.leave`アニメーションの両方を使用することは問題ありません。唯一の注意点はコンテンツプロジェクションです。レガシーアニメーションを持つコンポーネントから`animate.enter`または`animate.leave`を持つ別のコンポーネントにコンテンツをプロジェクトする場合、またはその逆の場合、これは同じコンポーネント内で一緒に使用した場合と同じ動作になります。これはサポートされていません。
+
## テスト {#testing}
TestBedは、テスト環境でアニメーションを有効または無効にするための組み込みサポートを提供します。CSSアニメーションはブラウザでの実行が必要であり、多くのAPIはテスト環境では利用できません。デフォルトでは、TestBedはテスト環境でアニメーションを無効にします。
diff --git a/adev-ja/src/content/guide/animations/migration.md b/adev-ja/src/content/guide/animations/migration.md
index 8ca357a02c..60890a1736 100644
--- a/adev-ja/src/content/guide/animations/migration.md
+++ b/adev-ja/src/content/guide/animations/migration.md
@@ -1,6 +1,6 @@
# Migrating away from Angular's Animations package
-The `@angular/animations` package is deprecated as of v20.2, which also introduced the new `animate.enter` and `animate.leave` feature to add animations to your application. Using these new features, you can replace all animations based on `@angular/animations` with plain CSS or JS animation libraries. Removing `@angular/animations` from your application can significantly reduce the size of your JavaScript bundle. Native CSS animations generally offer superior performance, as they can benefit from hardware acceleration. This guide walks through the process of refactoring your code from `@angular/animations` to native CSS animations.
+The `@angular/animations` package is deprecated as of v20.2, which also introduced the new `animate.enter` and `animate.leave` feature to add animations to your application. Using these new features, you can replace all animations based on `@angular/animations` with plain CSS or JS animation libraries. Removing `@angular/animations` from your application can significantly reduce the size of your JavaScript bundle. Native CSS animations generally offer superior performance, as they can benefit from hardware acceleration. This guide walks through the process of refactoring your code from `@angular/animations` to native CSS animations.
## How to write animations in native CSS
@@ -8,7 +8,7 @@ If you've never written any native CSS animations, there are a number of excelle
[MDN's CSS Animations guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations/Using_CSS_animations)
[W3Schools CSS3 Animations guide](https://www.w3schools.com/css/css3_animations.asp)
[The Complete CSS Animations Tutorial](https://www.lambdatest.com/blog/css-animations-tutorial/)
-[CSS Animation for Beginners](https://thoughtbot.com/blog/css-animation-for-beginners)
+[CSS Animation for Beginners](https://thoughtbot.com/blog/css-animation-for-beginners)
and a couple of videos:
[Learn CSS Animation in 9 Minutes](https://www.youtube.com/watch?v=z2LQYsZhsFw)
@@ -21,10 +21,12 @@ Check some of these various guides and tutorials out, and then come back to this
Just like with the animations package, you can create reusable animations that can be shared across your application. The animations package version of this had you using the `animation()` function in a shared typescript file. The native CSS version of this is similar, but lives in a shared CSS file.
#### With Animations Package
-
+
+
#### With Native CSS
-
+
+
Adding the class `animated-class` to an element would trigger the animation on that element.
@@ -35,12 +37,14 @@ Adding the class `animated-class` to an element would trigger the animation on t
The animations package allowed you to define various states using the [`state()`](api/animations/state) function within a component. Examples might be an `open` or `closed` state containing the styles for each respective state within the definition. For example:
#### With Animations Package
-
+
+
This same behavior can be accomplished natively by using CSS classes either using a keyframe animation or transition styling.
#### With Native CSS
-
+
+
Triggering the `open` or `closed` state is done by toggling classes on the element in your component. You can find examples of how to do this in our [template guide](guide/templates/binding#css-class-and-style-property-bindings).
@@ -52,28 +56,30 @@ The animations package `animate()` function allows for providing timing, like du
Specify `animation-duration`, `animation-delay`, and `animation-timing-function` for a keyframe animation in CSS, or alternatively use the `animation` shorthand property.
-
+
Similarly, you can use `transition-duration`, `transition-delay`, and `transition-timing-function` and the `transition` shorthand for animations that are not using `@keyframes`.
-
+
### Triggering an Animation
The animations package required specifying triggers using the `trigger()` function and nesting all of your states within it. With native CSS, this is unnecessary. Animations can be triggered by toggling CSS styles or classes. Once a class is present on an element, the animation will occur. Removing the class will revert the element back to whatever CSS is defined for that element. This results in significantly less code to do the same animation. Here's an example:
#### With Animations Package
+
-
-
-
+
+
+
#### With Native CSS
+
-
-
-
+
+
+
## Transition and Triggers
@@ -89,19 +95,21 @@ These state matching patterns are not needed at all when animating with CSS dire
The animations package offers the ability to animate things that have been historically difficult to animate, like animating a set height to `height: auto`. You can now do this with pure CSS as well.
#### With Animations Package
+
-
-
-
+
+
+
You can use css-grid to animate to auto height.
#### With Native CSS
+
-
-
-
+
+
+
If you don't have to worry about supporting all browsers, you can also check out `calc-size()`, which is the true solution to animating auto height. See [MDN's docs](https://developer.mozilla.org/en-US/docs/Web/CSS/calc-size) and (this tutorial)[https://frontendmasters.com/blog/one-of-the-boss-battles-of-css-is-almost-won-transitioning-to-auto/] for more information.
@@ -111,28 +119,31 @@ If you don't have to worry about supporting all browsers, you can also check out
The animations package offered the previously mentioned pattern matching for entering and leaving but also included the shorthand aliases of `:enter` and `:leave`.
#### With Animations Package
+
-
-
-
+
+
+
Here's how the same thing can be accomplished without the animations package using `animate.enter`.
#### With Native CSS
+
-
-
-
+
+
+
Use `animate.leave` to animate elements as they leave the view, which will apply the specified CSS classes to the element as it leaves the view.
#### With Native CSS
+
-
-
-
+
+
+
For more information on `animate.enter` and `animate.leave`, see the [Enter and Leave animations guide](guide/animations).
@@ -142,17 +153,19 @@ For more information on `animate.enter` and `animate.leave`, see the [Enter and
Along with the aforementioned `:enter` and `:leave`, there's also `:increment` and `:decrement`. You can animate these also by adding and removing classes. Unlike the animation package built-in aliases, there is no automatic application of classes when the values go up or down. You can apply the appropriate classes programmatically. Here's an example:
#### With Animations Package
+
-
-
-
+
+
+
#### With Native CSS
+
-
-
-
+
+
+
### Parent / Child Animations
@@ -185,12 +198,12 @@ The animations package exposed callbacks for you to use in the case that you wan
[`OnAnimationStart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationstart_event)
[`OnAnimationEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationend_event)
[`OnAnimationIteration`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationitration_event)
-[`OnAnimationCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event)
+[`OnAnimationCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event)
[`OnTransitionStart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionstart_event)
[`OnTransitionRun`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionrun_event)
[`OnTransitionEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionend_event)
-[`OnTransitionCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitioncancel_event)
+[`OnTransitionCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitioncancel_event)
The Web Animations API has a lot of additional functionality. [Take a look at the documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) to see all the available animation APIs.
@@ -211,17 +224,19 @@ To toggle classes for child nodes within a template, you can use class and style
The `stagger()` function allowed you to delay the animation of each item in a list of items by a specified time to create a cascade effect. You can replicate this behavior in native CSS by utilizing `animation-delay` or `transition-delay`. Here is an example of what that CSS might look like.
#### With Animations Package
+
-
-
-
+
+
+
#### With Native CSS
+
-
-
-
+
+
+
### Parallel Animations
@@ -241,20 +256,21 @@ In this example, the `rotate` and `fade-in` animations fire at the same time.
Items reordering in a list works out of the box using the previously described techniques. No additional special work is required. Items in a `@for` loop will be removed and re-added properly, which will fire off animations using `@starting-styles` for entry animations. Alternatively, you can use `animate.enter` for this same behavior. Use `animate.leave` to animate elements as they are removed, as seen in the example above.
#### With Animations Package<
+
-
-
-
+
+
+
#### With Native CSS
+
-
-
-
+
+
+
-
## Migrating usages of AnimationPlayer
The `AnimationPlayer` class allows access to an animation to do more advanced things like pause, play, restart, and finish an animation through code. All of these things can be handled natively as well.
@@ -263,4 +279,4 @@ You can retrieve animations off an element directly using [`Element.getAnimation
## Route Transitions
-You can use view transitions to animate between routes. See the [Route Transition Animations Guide](guide/routing/route-transition-animations) to get started.
\ No newline at end of file
+You can use view transitions to animate between routes. See the [Route Transition Animations Guide](guide/routing/route-transition-animations) to get started.
diff --git a/adev-ja/src/content/guide/animations/overview.md b/adev-ja/src/content/guide/animations/overview.md
index bb6991efb8..e1d042d634 100644
--- a/adev-ja/src/content/guide/animations/overview.md
+++ b/adev-ja/src/content/guide/animations/overview.md
@@ -6,11 +6,11 @@ Animation provides the illusion of motion: HTML elements change styling over tim
Well-designed animations can make your application more fun and straightforward to use, but they aren't just cosmetic.
Animations can improve your application and user experience in a number of ways:
-* Without animations, web page transitions can seem abrupt and jarring
-* Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions
-* Good animations intuitively call the user's attention to where it is needed
+- Without animations, web page transitions can seem abrupt and jarring
+- Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions
+- Good animations intuitively call the user's attention to where it is needed
-Typically, animations involve multiple style *transformations* over time.
+Typically, animations involve multiple style _transformations_ over time.
An HTML element can move, change color, grow or shrink, fade, or slide off the page.
These changes can occur simultaneously or sequentially. You can control the timing of each transformation.
@@ -49,12 +49,12 @@ bootstrapApplication(AppComponent, {
For `NgModule` based applications import `BrowserAnimationsModule`, which introduces the animation capabilities into your Angular root application module.
-
+
If you plan to use specific animation functions in component files, import those functions from `@angular/animations`.
-
+
See all [available animation functions](guide/legacy-animations#animations-api-summary) at the end of this guide.
@@ -63,7 +63,7 @@ See all [available animation functions](guide/legacy-animations#animations-api-s
In the component file, add a metadata property called `animations:` within the `@Component()` decorator.
You put the trigger that defines an animation within the `animations` metadata property.
-
+
@@ -82,11 +82,9 @@ HELPFUL: Let's create a new `open-close` component to animate with simple transi
Run the following command in terminal to generate the component:
-
-
+```shell
ng g component open-close
-
-
+```
This will create the component at `src/app/open-close.component.ts`.
@@ -97,24 +95,24 @@ This function takes two arguments:
A unique name like `open` or `closed` and a `style()` function.
Use the `style()` function to define a set of styles to associate with a given state name.
-You must use *camelCase* for style attributes that contain dashes, such as `backgroundColor` or wrap them in quotes, such as `'background-color'`.
+You must use _camelCase_ for style attributes that contain dashes, such as `backgroundColor` or wrap them in quotes, such as `'background-color'`.
Let's see how Angular's [`state()`](api/animations/state) function works with the `style()` function to set CSS style attributes.
In this code snippet, multiple style attributes are set at the same time for the state.
In the `open` state, the button has a height of 200 pixels, an opacity of 1, and a yellow background color.
-
+
In the following `closed` state, the button has a height of 100 pixels, an opacity of 0.8, and a background color of blue.
-
+
### Transitions and timing
In Angular, you can set multiple styles without any animation.
However, without further refinement, the button instantly transforms with no fade, no shrinkage, or other visible indicator that a change is occurring.
-To make the change less abrupt, you need to define an animation *transition* to specify the changes that occur between one state and another over a period of time.
+To make the change less abrupt, you need to define an animation _transition_ to specify the changes that occur between one state and another over a period of time.
The `transition()` function accepts two arguments:
The first argument accepts an expression that defines the direction between two transition states, and the second argument accepts one or a series of `animate()` steps.
@@ -146,40 +144,40 @@ The first part, `duration`, is required.
The duration can be expressed in milliseconds as a number without quotes, or in seconds with quotes and a time specifier.
For example, a duration of a tenth of a second can be expressed as follows:
-* As a plain number, in milliseconds:
- `100`
+- As a plain number, in milliseconds:
+ `100`
-* In a string, as milliseconds:
- `'100ms'`
+- In a string, as milliseconds:
+ `'100ms'`
-* In a string, as seconds:
- `'0.1s'`
+- In a string, as seconds:
+ `'0.1s'`
The second argument, `delay`, has the same syntax as `duration`.
For example:
-* Wait for 100ms and then run for 200ms: `'0.2s 100ms'`
+- Wait for 100ms and then run for 200ms: `'0.2s 100ms'`
The third argument, `easing`, controls how the animation [accelerates and decelerates](https://easings.net) during its runtime.
For example, `ease-in` causes the animation to begin slowly, and to pick up speed as it progresses.
-* Wait for 100ms, run for 200ms.
- Use a deceleration curve to start out fast and slowly decelerate to a resting point:
- `'0.2s 100ms ease-out'`
+- Wait for 100ms, run for 200ms.
+ Use a deceleration curve to start out fast and slowly decelerate to a resting point:
+ `'0.2s 100ms ease-out'`
-* Run for 200ms, with no delay.
- Use a standard curve to start slow, accelerate in the middle, and then decelerate slowly at the end:
- `'0.2s ease-in-out'`
+- Run for 200ms, with no delay.
+ Use a standard curve to start slow, accelerate in the middle, and then decelerate slowly at the end:
+ `'0.2s ease-in-out'`
-* Start immediately, run for 200ms.
- Use an acceleration curve to start slow and end at full velocity:
- `'0.2s ease-in'`
+- Start immediately, run for 200ms.
+ Use an acceleration curve to start slow and end at full velocity:
+ `'0.2s ease-in'`
HELPFUL: See the Material Design website's topic on [Natural easing curves](https://material.io/design/motion/speed.html#easing) for general information on easing curves.
This example provides a state transition from `open` to `closed` with a 1-second transition between states.
-
+
In the preceding code snippet, the `=>` operator indicates unidirectional transitions, and `<=>` is bidirectional.
Within the transition, `animate()` specifies how long the transition takes.
@@ -187,24 +185,24 @@ In this case, the state change from `open` to `closed` takes 1 second, expressed
This example adds a state transition from the `closed` state to the `open` state with a 0.5-second transition animation arc.
-
+
HELPFUL: Some additional notes on using styles within [`state`](api/animations/state) and `transition` functions.
-* Use [`state()`](api/animations/state) to define styles that are applied at the end of each transition, they persist after the animation completes
-* Use `transition()` to define intermediate styles, which create the illusion of motion during the animation
-* When animations are disabled, `transition()` styles can be skipped, but [`state()`](api/animations/state) styles can't
-* Include multiple state pairs within the same `transition()` argument:
+- Use [`state()`](api/animations/state) to define styles that are applied at the end of each transition, they persist after the animation completes
+- Use `transition()` to define intermediate styles, which create the illusion of motion during the animation
+- When animations are disabled, `transition()` styles can be skipped, but [`state()`](api/animations/state) styles can't
+- Include multiple state pairs within the same `transition()` argument:
- transition( 'on => off, off => void' )
+ transition( 'on => off, off => void' )
### Triggering the animation
-An animation requires a *trigger*, so that it knows when to start.
+An animation requires a _trigger_, so that it knows when to start.
The `trigger()` function collects the states and transitions, and gives the animation a name, so that you can attach it to the triggering element in the HTML template.
The `trigger()` function describes the property name to watch for changes.
@@ -222,7 +220,7 @@ However, it's possible for multiple triggers to be active at once.
Animations are defined in the metadata of the component that controls the HTML element to be animated.
Put the code that defines your animations under the `animations:` property within the `@Component()` decorator.
-
+
When you've defined an animation trigger for a component, attach it to an element in that component's template by wrapping the trigger name in brackets and preceding it with an `@` symbol.
Then, you can bind the trigger to a template expression using standard Angular property binding syntax as shown below, where `triggerName` is the name of the trigger, and `expression` evaluates to a defined animation state.
@@ -237,7 +235,7 @@ The animation is executed or triggered when the expression value changes to a ne
The following code snippet binds the trigger to the value of the `isOpen` property.
-
+
In this example, when the `isOpen` expression evaluates to a defined state of `open` or `closed`, it notifies the trigger `openClose` of a state change.
Then it's up to the `openClose` code to handle the state change and kick off a state change animation.
@@ -254,9 +252,9 @@ In the HTML template file, use the trigger name to attach the defined animations
Here are the code files discussed in the transition example.
-
-
-
+
+
+
### Summary
@@ -271,14 +269,14 @@ The functional API provided by the `@angular/animations` module provides a domai
See the [API reference](api#animations) for a complete listing and syntax details of the core functions and related data structures.
| Function name | What it does |
-|:--- |:--- |
+| :-------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `trigger()` | Kicks off the animation and serves as a container for all other animation function calls. HTML template binds to `triggerName`. Use the first argument to declare a unique trigger name. Uses array syntax. |
| `style()` | Defines one or more CSS styles to use in animations. Controls the visual appearance of HTML elements during animations. Uses object syntax. |
| [`state()`](api/animations/state) | Creates a named set of CSS styles that should be applied on successful transition to a given state. The state can then be referenced by name within other animation functions. |
| `animate()` | Specifies the timing information for a transition. Optional values for `delay` and `easing`. Can contain `style()` calls within. |
| `transition()` | Defines the animation sequence between two named states. Uses array syntax. |
| `keyframes()` | Allows a sequential change between styles within a specified time interval. Use within `animate()`. Can include multiple `style()` calls within each `keyframe()`. Uses array syntax. |
-| [`group()`](api/animations/group) | Specifies a group of animation steps \(*inner animations*\) to be run in parallel. Animation continues only after all inner animation steps have completed. Used within `sequence()` or `transition()`. |
+| [`group()`](api/animations/group) | Specifies a group of animation steps \(_inner animations_\) to be run in parallel. Animation continues only after all inner animation steps have completed. Used within `sequence()` or `transition()`. |
| `query()` | Finds one or more inner HTML elements within the current element. |
| `sequence()` | Specifies a list of animation steps that are run sequentially, one by one. |
| `stagger()` | Staggers the starting time for animations for multiple elements. |
diff --git a/adev-ja/src/content/guide/animations/reusable-animations.md b/adev-ja/src/content/guide/animations/reusable-animations.md
index d8d024fab7..17c2e9bdd8 100644
--- a/adev-ja/src/content/guide/animations/reusable-animations.md
+++ b/adev-ja/src/content/guide/animations/reusable-animations.md
@@ -9,7 +9,7 @@ This topic provides some examples of how to create reusable animations.
To create a reusable animation, use the [`animation()`](api/animations/animation) function to define an animation in a separate `.ts` file and declare this animation definition as a `const` export variable.
You can then import and reuse this animation in any of your application components using the [`useAnimation()`](api/animations/useAnimation) function.
-
+
In the preceding code snippet, `transitionAnimation` is made reusable by declaring it as an export variable.
@@ -18,12 +18,12 @@ HELPFUL: The `height`, `opacity`, `backgroundColor`, and `time` inputs are repla
You can also export a part of an animation.
For example, the following snippet exports the animation `trigger`.
-
+
From this point, you can import reusable animation variables in your component class.
For example, the following code snippet imports the `transitionAnimation` variable and uses it via the `useAnimation()` function.
-
+
## More on Angular animations
diff --git a/adev-ja/src/content/guide/animations/transition-and-triggers.md b/adev-ja/src/content/guide/animations/transition-and-triggers.md
index cc35138022..13be61108d 100644
--- a/adev-ja/src/content/guide/animations/transition-and-triggers.md
+++ b/adev-ja/src/content/guide/animations/transition-and-triggers.md
@@ -11,7 +11,7 @@ In Angular, transition states can be defined explicitly through the [`state()`](
### Wildcard state
-An asterisk `*` or *wildcard* matches any animation state.
+An asterisk `*` or _wildcard_ matches any animation state.
This is useful for defining transitions that apply regardless of the HTML element's start or end state.
For example, a transition of `open => *` applies when the element's state changes from open to anything else.
@@ -23,11 +23,11 @@ Instead of defining each state-to-state transition pair, any transition to `clos
This allows the addition of new states without having to include separate transitions for each one.
-
+
Use a double arrow syntax to specify state-to-state transitions in both directions.
-
+
### Use wildcard state with multiple transition states
@@ -37,7 +37,7 @@ If the button can change from `open` to either `closed` or something like `inPro
-
+
The `* => *` transition applies when any change between two states takes place.
@@ -45,14 +45,14 @@ Transitions are matched in the order in which they are defined.
Thus, you can apply other transitions on top of the `* => *` transition.
For example, define style changes or animations that would apply just to `open => closed`, then use `* => *` as a fallback for state pairings that aren't otherwise called out.
-To do this, list the more specific transitions *before* `* => *`.
+To do this, list the more specific transitions _before_ `* => *`.
### Use wildcards with styles
Use the wildcard `*` with a style to tell the animation to use whatever the current style value is, and animate with that.
Wildcard is a fallback value that's used if the state being animated isn't declared within the trigger.
-
+
### Void state
@@ -63,9 +63,9 @@ See [Animating entering and leaving a view](guide/legacy-animations/transition-a
Combine wildcard and void states in a transition to trigger animations that enter and leave the page:
-* A transition of `* => void` applies when the element leaves a view, regardless of what state it was in before it left
-* A transition of `void => *` applies when the element enters a view, regardless of what state it assumes when entering
-* The wildcard state `*` matches to *any* state, including `void`
+- A transition of `* => void` applies when the element leaves a view, regardless of what state it was in before it left
+- A transition of `void => *` applies when the element enters a view, regardless of what state it assumes when entering
+- The wildcard state `*` matches to _any_ state, including `void`
## Animate entering and leaving a view
@@ -73,10 +73,10 @@ This section shows how to animate elements entering or leaving a page.
Add a new behavior:
-* When you add a hero to the list of heroes, it appears to fly onto the page from the left
-* When you remove a hero from the list, it appears to fly out to the right
+- When you add a hero to the list of heroes, it appears to fly onto the page from the left
+- When you remove a hero from the list, it appears to fly out to the right
-
+
In the preceding code, you applied the `void` state when the HTML element isn't attached to a view.
@@ -87,8 +87,8 @@ These aliases are used by several animation functions.
-transition ( ':enter', [ … ] ); // alias for void => *
-transition ( ':leave', [ … ] ); // alias for * => void
+transition ( ':enter', [ … ] ); // alias for void => _
+transition ( ':leave', [ … ] ); // alias for _ => void
@@ -105,11 +105,11 @@ As a rule of thumb consider that any element being added to the DOM by Angular p
This example has a special trigger for the enter and leave animation called `myInsertRemoveTrigger`.
The HTML template contains the following code.
-
+
In the component file, the `:enter` transition sets an initial opacity of 0. It then animates it to change that opacity to 1 as the element is inserted into the view.
-
+
Note that this example doesn't need to use [`state()`](api/animations/state).
@@ -121,13 +121,13 @@ Use these to kick off a transition when a numeric value has increased or decreas
HELPFUL: The following example uses `query()` and `stagger()` methods.
For more information on these methods, see the [complex sequences](guide/legacy-animations/complex-sequences) page.
-
+
## Boolean values in transitions
If a trigger contains a Boolean value as a binding value, then this value can be matched using a `transition()` expression that compares `true` and `false`, or `1` and `0`.
-
+
In the code snippet above, the HTML template binds a `
` element to a trigger named `openClose` with a status expression of `isOpen`, and with possible values of `true` and `false`.
This pattern is an alternative to the practice of creating two named states like `open` and `close`.
@@ -136,7 +136,7 @@ Inside the `@Component` metadata under the `animations:` property, when the stat
In this case, the animation uses whatever height the element already had before the animation started.
When the element is `closed`, the element gets animated to a height of 0, which makes it invisible.
-
+
## Multiple animation triggers
@@ -156,8 +156,8 @@ When true, the `@.disabled` binding prevents all animations from rendering.
The following code sample shows how to use this feature.
-
-
+
+
When the `@.disabled` binding is true, the `@childAnimation` trigger doesn't kick off.
@@ -167,31 +167,31 @@ You can't selectively turn off multiple animations on a single element.
-* A child animation can be queried by a parent and then later animated with the `animateChild()` function
+- A child animation can be queried by a parent and then later animated with the `animateChild()` function
#### Disable all animations
To turn off all animations for an Angular application, place the `@.disabled` host binding on the topmost Angular component.
-
+
HELPFUL: Disabling animations application-wide is useful during end-to-end \(E2E\) testing.
## Animation callbacks
-The animation `trigger()` function emits *callbacks* when it starts and when it finishes.
+The animation `trigger()` function emits _callbacks_ when it starts and when it finishes.
The following example features a component that contains an `openClose` trigger.
-
+
In the HTML template, the animation event is passed back via `$event`, as `@triggerName.start` and `@triggerName.done`, where `triggerName` is the name of the trigger being used.
In this example, the trigger `openClose` appears as follows.
-
+
A potential use for animation callbacks could be to cover for a slow API call, such as a database lookup.
For example, an **InProgress** button can be set up to have its own looping animation while the backend system operation finishes.
@@ -199,16 +199,16 @@ For example, an **InProgress** button can be set up to have its own looping anim
Another animation can be called when the current animation finishes.
For example, the button goes from the `inProgress` state to the `closed` state when the API call is completed.
-An animation can influence an end user to *perceive* the operation as faster, even when it is not.
+An animation can influence an end user to _perceive_ the operation as faster, even when it is not.
Callbacks can serve as a debugging tool, for example in conjunction with `console.warn()` to view the application's progress in a browser's Developer JavaScript Console.
The following code snippet creates console log output for the original example, a button with the two states of `open` and `closed`.
-
+
## Keyframes
-To create an animation with multiple steps run in sequence, use *keyframes*.
+To create an animation with multiple steps run in sequence, use _keyframes_.
Angular's `keyframe()` function allows several style changes within a single timing segment.
For example, the button, instead of fading, could change color several times over a single 2-second time span.
@@ -217,7 +217,7 @@ For example, the button, instead of fading, could change color several times ove
The code for this color change might look like this.
-
+
### Offset
@@ -233,7 +233,7 @@ Specifying an offset of 0.8 for the middle transition in the preceding example m
The code with offsets specified would be as follows.
-
+
You can combine keyframes with `duration`, `delay`, and `easing` within a single animation.
@@ -243,14 +243,14 @@ Use keyframes to create a pulse effect in your animations by defining styles at
Here's an example of using keyframes to create a pulse effect:
-* The original `open` and `closed` states, with the original changes in height, color, and opacity, occurring over a timeframe of 1 second
-* A keyframes sequence inserted in the middle that causes the button to appear to pulsate irregularly over the course of that same 1 second timeframe
+- The original `open` and `closed` states, with the original changes in height, color, and opacity, occurring over a timeframe of 1 second
+- A keyframes sequence inserted in the middle that causes the button to appear to pulsate irregularly over the course of that same 1 second timeframe
The code snippet for this animation might look like this.
-
+
### Animatable properties and units
@@ -260,14 +260,14 @@ The W3C maintains a list of animatable properties on its [CSS Transitions](https
For properties with a numeric value, define a unit by providing the value as a string, in quotes, with the appropriate suffix:
-* 50 pixels:
- `'50px'`
+- 50 pixels:
+ `'50px'`
-* Relative font size:
- `'3em'`
+- Relative font size:
+ `'3em'`
-* Percentage:
- `'100%'`
+- Percentage:
+ `'100%'`
You can also provide the value as a number. In such cases Angular assumes a default unit of pixels, or `px`.
Expressing 50 pixels as `50` is the same as saying `'50px'`.
@@ -285,7 +285,7 @@ In these cases, you can use a special wildcard `*` property value under `style()
The following example has a trigger called `shrinkOut`, used when an HTML element leaves the page.
The animation takes whatever height the element has before it leaves, and animates from that height to zero.
-
+
### Keyframes summary
diff --git a/adev-ja/src/content/guide/aria/accordion.md b/adev-ja/src/content/guide/aria/accordion.md
index dbe528b255..990da2c19c 100644
--- a/adev-ja/src/content/guide/aria/accordion.md
+++ b/adev-ja/src/content/guide/aria/accordion.md
@@ -1,23 +1,251 @@
-
-
-
+
+
+## Overview
-
+## Usage
-### Example with TailwindCSS
+Accordions work well for organizing content into logical groups where users typically need to view one section at a time.
-
+**Use accordions when:**
+
+- Displaying FAQs with multiple questions and answers
+- Organizing long forms into manageable sections
+- Reducing scrolling on content-heavy pages
+- Progressively disclosing related information
+
+**Avoid accordions when:**
+
+- Building navigation menus (use the [Menu](guide/aria/menu) component instead)
+- Creating tabbed interfaces (use the [Tabs](guide/aria/tabs) component instead)
+- Showing a single collapsible section (use a disclosure pattern instead)
+- Users need to see multiple sections simultaneously (consider a different layout)
+
+## Features
+
+- **Expansion modes** - Control whether one or multiple panels can be open at the same time
+- **Keyboard navigation** - Navigate between triggers using arrow keys, Home, and End
+- **Lazy rendering** - Content is only created when a panel first expands, improving initial load performance
+- **Disabled states** - Disable the entire group or individual triggers
+- **Focus management** - Control whether disabled items can receive keyboard focus
+- **Programmatic control** - Expand, collapse, or toggle panels from your component code
+- **RTL support** - Automatic support for right-to-left languages
+
+## Examples
+
+### Single expansion mode
+
+Set `[multiExpandable]="false"` to allow only one panel to be open at a time. Opening a new panel automatically closes any previously open panel.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+This mode works well for FAQs or situations where you want users to focus on one answer at a time.
+
+### Multiple expansion mode
+
+Set `[multiExpandable]="true"` to allow multiple panels to be open simultaneously. Users can expand as many panels as needed without closing others.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+This mode is useful for form sections or when users need to compare content across multiple panels.
+
+NOTE: The `multiExpandable` input defaults to `true`. Set it to `false` explicitly if you want single expansion behavior.
+
+### Disabled accordion items
+
+Disable specific triggers using the `disabled` input. Control how disabled items behave during keyboard navigation using the `softDisabled` input on the accordion group.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+When `[softDisabled]="true"` (the default), disabled items can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled items are skipped entirely during keyboard navigation.
+
+### Lazy content rendering
+
+Use the `ngAccordionContent` directive on an `ng-template` to defer rendering content until the panel first expands. This improves performance for accordions with heavy content like images, charts, or complex components.
+
+```angular-html
+
+
+
+ Trigger Text
+
+
+
+
+
+
+
+
+
+
+```
+
+By default, content remains in the DOM after the panel collapses. Set `[preserveContent]="false"` to remove the content from the DOM when the panel closes.
+
+## APIs
+
+### AccordionGroup
+
+The container directive that manages keyboard navigation and expansion behavior for a group of accordion items.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ----------------- | --------- | ------- | ------------------------------------------------------------------------- |
+| `disabled` | `boolean` | `false` | Disables all triggers in the group |
+| `multiExpandable` | `boolean` | `true` | Whether multiple panels can be expanded simultaneously |
+| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable. When `false`, they are skipped |
+| `wrap` | `boolean` | `false` | Whether keyboard navigation wraps from last to first item and vice versa |
+
+#### Methods
+
+| Method | Parameters | Description |
+| ------------- | ---------- | ---------------------------------------------------------------- |
+| `expandAll` | none | Expands all panels (only works when `multiExpandable` is `true`) |
+| `collapseAll` | none | Collapses all panels |
+
+### AccordionTrigger
+
+The directive applied to the button element that toggles panel visibility.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | --------- | ------- | -------------------------------------------------------------- |
+| `id` | `string` | auto | Unique identifier for the trigger |
+| `panelId` | `string` | — | **Required.** Must match the `panelId` of the associated panel |
+| `disabled` | `boolean` | `false` | Disables this trigger |
+| `expanded` | `boolean` | `false` | Whether the panel is expanded (supports two-way binding) |
+
+#### Signals
+
+| Property | Type | Description |
+| -------- | ----------------- | --------------------------------------- |
+| `active` | `Signal` | Whether the trigger currently has focus |
+
+#### Methods
+
+| Method | Parameters | Description |
+| ---------- | ---------- | --------------------------------- |
+| `expand` | none | Expands the associated panel |
+| `collapse` | none | Collapses the associated panel |
+| `toggle` | none | Toggles the panel expansion state |
+
+### AccordionPanel
+
+The directive applied to the element containing the collapsible content.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ----------------- | --------- | ------- | ---------------------------------------------------------------- |
+| `id` | `string` | auto | Unique identifier for the panel |
+| `panelId` | `string` | — | **Required.** Must match the `panelId` of the associated trigger |
+| `preserveContent` | `boolean` | `true` | Whether to keep content in DOM after panel collapses |
+
+#### Signals
+
+| Property | Type | Description |
+| --------- | ----------------- | --------------------------------------- |
+| `visible` | `Signal` | Whether the panel is currently expanded |
+
+#### Methods
+
+| Method | Parameters | Description |
+| ---------- | ---------- | --------------------------- |
+| `expand` | none | Expands this panel |
+| `collapse` | none | Collapses this panel |
+| `toggle` | none | Toggles the expansion state |
+
+### AccordionContent
+
+The structural directive applied to an `ng-template` inside an accordion panel to enable lazy rendering.
+
+This directive has no inputs, outputs, or methods. Apply it to an `ng-template` element:
+
+```angular-html
+
+
+
+
+
+```
diff --git a/adev-ja/src/content/guide/aria/autocomplete.md b/adev-ja/src/content/guide/aria/autocomplete.md
new file mode 100644
index 0000000000..f1fd46946e
--- /dev/null
+++ b/adev-ja/src/content/guide/aria/autocomplete.md
@@ -0,0 +1,190 @@
+
+
+
+## Overview
+
+An accessible input field that filters and suggests options as users type, helping them find and select values from a list.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Usage
+
+Autocomplete works best when users need to select from a large set of options where typing is faster than scrolling. Consider using autocomplete when:
+
+- **The option list is long** (more than 20 items) - Typing narrows down choices faster than scrolling through a dropdown
+- **Users know what they're looking for** - They can type part of the expected value (like a state name, product, or username)
+- **Options follow predictable patterns** - Users can guess partial matches (like country codes, email domains, or categories)
+- **Speed matters** - Forms benefit from quick selection without extensive navigation
+
+Avoid autocomplete when:
+
+- The list has fewer than 10 options - A regular dropdown or radio group provides better visibility
+- Users need to browse options - If discovery is important, show all options upfront
+- Options are unfamiliar - Users can't type what they don't know exists in the list
+
+## Features
+
+Angular's autocomplete provides a fully accessible combobox implementation with:
+
+- **Keyboard Navigation** - Navigate options with arrow keys, select with Enter, close with Escape
+- **Screen Reader Support** - Built-in ARIA attributes for assistive technologies
+- **Three Filter Modes** - Choose between auto-select, manual selection, or highlighting behavior
+- **Signal-Based Reactivity** - Reactive state management using Angular signals
+- **Popover API Integration** - Leverages the native HTML Popover API for optimal positioning
+- **Bidirectional Text Support** - Automatically handles right-to-left (RTL) languages
+
+## Examples
+
+### Auto-select mode
+
+Users typing partial text expect immediate confirmation that their input matches an available option. Auto-select mode updates the input value to match the first filtered option as users type, reducing the number of keystrokes needed and providing instant feedback that their search is on the right track.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Manual selection mode
+
+Manual selection mode keeps the typed text unchanged while users navigate the suggestion list, preventing confusion from automatic updates. The input only changes when users explicitly confirm their choice with Enter or a click.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Highlight mode
+
+Highlight mode allows the user to navigate options with arrow keys without changing the input value as they browse until they explicitly select a new option with Enter or click.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## APIs
+
+### Combobox Directive
+
+The `ngCombobox` directive provides the container for autocomplete functionality.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ------------ | ---------------------------------------------- | ---------- | ------------------------------------------------- |
+| `filterMode` | `'auto-select'` \| `'manual'` \| `'highlight'` | `'manual'` | Controls selection behavior |
+| `disabled` | `boolean` | `false` | Disables the combobox |
+| `firstMatch` | `string` | - | The value of the first matching item in the popup |
+
+#### Outputs
+
+| Property | Type | Description |
+| ---------- | ----------------- | ----------------------------------------------------- |
+| `expanded` | `Signal` | Signal indicating whether the popup is currently open |
+
+### ComboboxInput Directive
+
+The `ngComboboxInput` directive connects an input element to the combobox.
+
+#### Model
+
+| Property | Type | Description |
+| -------- | -------- | ------------------------------------------------------------ |
+| `value` | `string` | Two-way bindable string value of the input using `[(value)]` |
+
+### ComboboxPopupContainer Directive
+
+The `ngComboboxPopupContainer` directive wraps the popup content and manages its display.
+
+Must be used with `` inside a popover element.
+
+### Related components
+
+Autocomplete uses [Listbox](/api/aria/listbox/Listbox) and [Option](/api/aria/listbox/Option) directives to render the suggestion list. See the [Listbox documentation](/guide/aria/listbox) for additional customization options.
diff --git a/adev-ja/src/content/guide/aria/combobox.md b/adev-ja/src/content/guide/aria/combobox.md
index 0a55387723..858eb4865e 100644
--- a/adev-ja/src/content/guide/aria/combobox.md
+++ b/adev-ja/src/content/guide/aria/combobox.md
@@ -1,23 +1,255 @@
-
-
-
+
+
+## Overview
-
+
+
+
+
+
+
+
-### Example with TailwindCSS
+
+
+
+
+
+
+
+
-
+## Usage
+
+Combobox is the primitive directive that coordinates a text input with a popup. It provides the foundation for autocomplete, select, and multiselect patterns. Consider using combobox directly when:
+
+- **Building custom autocomplete patterns** - Creating specialized filtering or suggestion behavior
+- **Creating custom selection components** - Developing dropdowns with unique requirements
+- **Coordinating input with popup** - Pairing text input with listbox, tree, or dialog content
+- **Implementing specific filter modes** - Using manual, auto-select, or highlight behaviors
+
+Use documented patterns instead when:
+
+- Standard autocomplete with filtering is needed - See the [Autocomplete pattern](guide/aria/autocomplete) for ready-to-use examples
+- Single-selection dropdowns are needed - See the [Select pattern](guide/aria/select) for complete dropdown implementation
+- Multiple-selection dropdowns are needed - See the [Multiselect pattern](guide/aria/multiselect) for multi-select with compact display
+
+Note: The [Autocomplete](guide/aria/autocomplete), [Select](guide/aria/select), and [Multiselect](guide/aria/multiselect) guides show documented patterns that combine this directive with [Listbox](guide/aria/listbox) for specific use cases.
+
+## Features
+
+Angular's combobox provides a fully accessible input-popup coordination system with:
+
+- **Text Input with Popup** - Coordinates input field with popup content
+- **Three Filter Modes** - Manual, auto-select, or highlight behaviors
+- **Keyboard Navigation** - Arrow keys, Enter, Escape handling
+- **Screen Reader Support** - Built-in ARIA attributes including role="combobox" and aria-expanded
+- **Popup Management** - Automatic show/hide based on user interaction
+- **Signal-Based Reactivity** - Reactive state management using Angular signals
+
+## Examples
+
+### Autocomplete
+
+An accessible input field that filters and suggests options as users type, helping them find and select values from a list.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The `filterMode="manual"` setting gives complete control over filtering and selection. The input updates a signal that filters the options list. Users navigate with arrow keys and select with Enter or click. This mode provides the most flexibility for custom filtering logic. See the [Autocomplete guide](guide/aria/autocomplete) for complete filtering patterns and examples.
+
+### Readonly mode
+
+A pattern that combines a readonly combobox with listbox to create single-selection dropdowns with keyboard navigation and screen reader support.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The `readonly` attribute prevents typing in the input field. The popup opens on click or arrow keys. Users navigate options with keyboard and select with Enter or click.
+
+This configuration provides the foundation for the [Select](guide/aria/select) and [Multiselect](guide/aria/multiselect) patterns. See those guides for complete dropdown implementations with triggers and overlay positioning.
+
+### Dialog popup
+
+Popups sometimes need modal behavior with a backdrop and focus trap. The combobox dialog directive provides this pattern for specialized use cases.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The `ngComboboxDialog` directive creates a modal popup using the native dialog element. This provides backdrop behavior and focus trapping. Use dialog popups when the selection interface requires modal interaction or when the popup content is complex enough to warrant full-screen focus.
+
+## APIs
+
+### Combobox Directive
+
+The `ngCombobox` directive coordinates a text input with a popup.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------------- | ---------------------------------------------- | ---------- | ------------------------------------------------ |
+| `filterMode` | `'manual'` \| `'auto-select'` \| `'highlight'` | `'manual'` | Controls selection behavior |
+| `disabled` | `boolean` | `false` | Disables the combobox |
+| `readonly` | `boolean` | `false` | Makes combobox readonly (for Select/Multiselect) |
+| `firstMatch` | `V` | - | Value of first matching item for auto-select |
+| `alwaysExpanded` | `boolean` | `false` | Keeps popup always open |
+
+**Filter Modes:**
+
+- **`'manual'`** - User controls filtering and selection explicitly. The popup shows options based on your filtering logic. Users select with Enter or click. This mode provides the most flexibility.
+- **`'auto-select'`** - Input value automatically updates to the first matching option as users type. Requires the `firstMatch` input for coordination. See the [Autocomplete guide](guide/aria/autocomplete#auto-select-mode) for examples.
+- **`'highlight'`** - Highlights matching text without changing the input value. Users navigate with arrow keys and select with Enter.
+
+#### Signals
+
+| Property | Type | Description |
+| ---------- | ----------------- | ------------------------------- |
+| `expanded` | `Signal` | Whether popup is currently open |
+
+#### Methods
+
+| Method | Parameters | Description |
+| ---------- | ---------- | ---------------------- |
+| `open` | none | Opens the combobox |
+| `close` | none | Closes the combobox |
+| `expand` | none | Expands the combobox |
+| `collapse` | none | Collapses the combobox |
+
+### ComboboxInput Directive
+
+The `ngComboboxInput` directive connects an input element to the combobox.
+
+#### Model
+
+| Property | Type | Description |
+| -------- | -------- | ---------------------------------------- |
+| `value` | `string` | Two-way bindable value using `[(value)]` |
+
+The input element receives keyboard handling and ARIA attributes automatically.
+
+### ComboboxPopup Directive
+
+The `ngComboboxPopup` directive (host directive) manages popup visibility and coordination. Typically used with `ngComboboxPopupContainer` in an `ng-template` or with CDK Overlay.
+
+### ComboboxPopupContainer Directive
+
+The `ngComboboxPopupContainer` directive marks an `ng-template` as the popup content.
+
+```html
+
+
...
+
+```
+
+Used with Popover API or CDK Overlay for positioning.
+
+### ComboboxDialog Directive
+
+The `ngComboboxDialog` directive creates a modal combobox popup.
+
+```html
+
+```
+
+Use for modal popup behavior with backdrop and focus trap.
+
+### Related patterns and directives
+
+Combobox is the primitive directive for these documented patterns:
+
+- **[Autocomplete](guide/aria/autocomplete)** - Filtering and suggestions pattern (uses Combobox with filter modes)
+- **[Select](guide/aria/select)** - Single selection dropdown pattern (uses Combobox with `readonly`)
+- **[Multiselect](guide/aria/multiselect)** - Multiple selection pattern (uses Combobox with `readonly` + multi-enabled Listbox)
+
+Combobox typically combines with:
+
+- **[Listbox](guide/aria/listbox)** - Most common popup content
+- **[Tree](guide/aria/tree)** - Hierarchical popup content (see Tree guide for examples)
diff --git a/adev-ja/src/content/guide/aria/grid.md b/adev-ja/src/content/guide/aria/grid.md
index 41d1f215c2..6545e3045b 100644
--- a/adev-ja/src/content/guide/aria/grid.md
+++ b/adev-ja/src/content/guide/aria/grid.md
@@ -1,23 +1,214 @@
-
-
-
+
+
+## Overview
-
+## Usage
-### Example with TailwindCSS
+Grids work well for data or interactive elements organized in rows and columns where users need keyboard navigation in multiple directions.
-
+**Use grids when:**
+
+- Building interactive data tables with editable or selectable cells
+- Creating calendars or date pickers
+- Implementing spreadsheet-like interfaces
+- Grouping interactive elements (buttons, checkboxes) to reduce tab stops on a page
+- Building interfaces requiring two-dimensional keyboard navigation
+
+**Avoid grids when:**
+
+- Displaying simple read-only tables (use semantic HTML `
` instead)
+- Showing single-column lists (use [Listbox](guide/aria/listbox) instead)
+- Displaying hierarchical data (use [Tree](guide/aria/tree) instead)
+- Building forms without tabular layout (use standard form controls)
+
+## Features
+
+- **Two-dimensional navigation** - Arrow keys move between cells in all directions
+- **Focus modes** - Choose between roving tabindex or activedescendant focus strategies
+- **Selection support** - Optional cell selection with single or multi-select modes
+- **Wrapping behavior** - Configure how navigation wraps at grid edges (continuous, loop, or nowrap)
+- **Range selection** - Select multiple cells with modifier keys or dragging
+- **Disabled states** - Disable the entire grid or individual cells
+- **RTL support** - Automatic right-to-left language navigation
+
+## Examples
+
+### Data table grid
+
+Use a grid for interactive tables where users need to navigate between cells using arrow keys. This example shows a basic data table with keyboard navigation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Apply the `ngGrid` directive to the table element, `ngGridRow` to each row, and `ngGridCell` to each cell.
+
+### Calendar grid
+
+Calendars are a common use case for grids. This example shows a month view where users navigate dates using arrow keys.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Users can activate a date by pressing Enter or Space when focused on a cell.
+
+### Layout grid
+
+Use a layout grid to group interactive elements and reduce tab stops. This example shows a grid of pill buttons.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Instead of tabbing through each button, users navigate with arrow keys and only one button receives tab focus.
+
+### Selection and focus modes
+
+Enable selection with `[enableSelection]="true"` and configure how focus and selection interact.
+
+```angular-html
+
+
+
Cell 1
+
Cell 2
+
+
+```
+
+**Selection modes:**
+
+- `follow`: Focused cell is automatically selected
+- `explicit`: Users select cells with Space or click
+
+**Focus modes:**
+
+- `roving`: Focus moves to cells using `tabindex` (better for simple grids)
+- `activedescendant`: Focus stays on grid container, `aria-activedescendant` indicates active cell (better for virtual scrolling)
+
+## APIs
+
+### Grid
+
+The container directive that provides keyboard navigation and focus management for rows and cells.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------------------- | ------------------------------------ | ---------- | ------------------------------------------------------------- |
+| `enableSelection` | `boolean` | `false` | Whether selection is enabled for the grid |
+| `disabled` | `boolean` | `false` | Disables the entire grid |
+| `softDisabled` | `boolean` | `true` | When `true`, disabled cells are focusable but not interactive |
+| `focusMode` | `'roving' \| 'activedescendant'` | `'roving'` | Focus strategy used by the grid |
+| `rowWrap` | `'continuous' \| 'loop' \| 'nowrap'` | `'loop'` | Navigation wrapping behavior along rows |
+| `colWrap` | `'continuous' \| 'loop' \| 'nowrap'` | `'loop'` | Navigation wrapping behavior along columns |
+| `multi` | `boolean` | `false` | Whether multiple cells can be selected |
+| `selectionMode` | `'follow' \| 'explicit'` | `'follow'` | Whether selection follows focus or requires explicit action |
+| `enableRangeSelection` | `boolean` | `false` | Enable range selections with modifier keys or dragging |
+
+### GridRow
+
+Represents a row within a grid and serves as a container for grid cells.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | -------- | ------- | ------------------------------------- |
+| `rowIndex` | `number` | auto | The index of this row within the grid |
+
+### GridCell
+
+Represents an individual cell within a grid row.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ------------- | ---------------------------- | -------------- | ------------------------------------------------------- |
+| `id` | `string` | auto | Unique identifier for the cell |
+| `role` | `string` | `'gridcell'` | Cell role: `gridcell`, `columnheader`, or `rowheader` |
+| `disabled` | `boolean` | `false` | Disables this cell |
+| `selected` | `boolean` | `false` | Whether the cell is selected (supports two-way binding) |
+| `selectable` | `boolean` | `true` | Whether the cell can be selected |
+| `rowSpan` | `number` | — | Number of rows the cell spans |
+| `colSpan` | `number` | — | Number of columns the cell spans |
+| `rowIndex` | `number` | — | Row index of the cell |
+| `colIndex` | `number` | — | Column index of the cell |
+| `orientation` | `'vertical' \| 'horizontal'` | `'horizontal'` | Orientation for widgets within the cell |
+| `wrap` | `boolean` | `true` | Whether widget navigation wraps within the cell |
+
+#### Signals
+
+| Property | Type | Description |
+| -------- | ----------------- | ------------------------------------ |
+| `active` | `Signal` | Whether the cell currently has focus |
diff --git a/adev-ja/src/content/guide/aria/listbox.md b/adev-ja/src/content/guide/aria/listbox.md
index 1249852fb7..0255ee6894 100644
--- a/adev-ja/src/content/guide/aria/listbox.md
+++ b/adev-ja/src/content/guide/aria/listbox.md
@@ -1,23 +1,188 @@
-
-
-
-
-
+## Overview
+
+A directive that displays a list of options for users to select from, supporting keyboard navigation, single or multiple selection, and screen reader support.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Usage
+
+Listbox is a foundational directive used by the [Select](guide/aria/select), [Multiselect](guide/aria/multiselect), and [Autocomplete](guide/aria/autocomplete) patterns. For most dropdown needs, use those documented patterns instead.
+
+Consider using listbox directly when:
+
+- **Building custom selection components** - Creating specialized interfaces with specific behavior
+- **Visible selection lists** - Displaying selectable items directly on the page (not in dropdowns)
+- **Custom integration patterns** - Integrating with unique popup or layout requirements
+
+Avoid listbox when:
+
+- **Navigation menus are needed** - Use the [Menu](guide/aria/menu) directive for actions and commands
+
+## Features
+Angular's listbox provides a fully accessible list implementation with:
-
+The `values` model signal provides two-way binding to the selected items. With `selectionMode="explicit"`, users press Space or Enter to select options. For dropdown patterns that combine listbox with combobox and overlay positioning, see the [Select](guide/aria/select) pattern.
+
+### Horizontal listbox
+
+Lists sometimes work better horizontally, such as toolbar-like interfaces or tab-style selections. The `orientation` attribute changes both the layout and keyboard navigation direction.
+
+
+
+
+
+
+
+
+
-### Example with TailwindCSS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+With `orientation="horizontal"`, left and right arrow keys navigate between options instead of up and down. The listbox automatically handles right-to-left (RTL) languages by reversing navigation direction.
+
+### Selection modes
+
+Listbox supports two selection modes that control when items become selected. Choose the mode that matches your interface's interaction pattern.
+
+
+
+
+
-
+The `'follow'` mode automatically selects the focused item, providing faster interaction when selection changes frequently. The `'explicit'` mode requires Space or Enter to confirm selection, preventing accidental changes while navigating. Dropdown patterns typically use `'follow'` mode for single selection.
+
+## APIs
+
+### Listbox Directive
+
+The `ngListbox` directive creates an accessible list of selectable options.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------------- | ---------------------------------- | ------------ | -------------------------------------------- |
+| `id` | `string` | auto | Unique identifier for the listbox |
+| `multi` | `boolean` | `false` | Enables multiple selection |
+| `orientation` | `'vertical'` \| `'horizontal'` | `'vertical'` | Layout direction of the list |
+| `wrap` | `boolean` | `true` | Whether focus wraps at list edges |
+| `selectionMode` | `'follow'` \| `'explicit'` | `'follow'` | How selection is triggered |
+| `focusMode` | `'roving'` \| `'activedescendant'` | `'roving'` | Focus management strategy |
+| `softDisabled` | `boolean` | `true` | Whether disabled items are focusable |
+| `disabled` | `boolean` | `false` | Disables the entire listbox |
+| `readonly` | `boolean` | `false` | Makes listbox readonly |
+| `typeaheadDelay` | `number` | `500` | Milliseconds before type-ahead search resets |
+
+#### Model
+
+| Property | Type | Description |
+| -------- | ----- | ----------------------------------------- |
+| `values` | `V[]` | Two-way bindable array of selected values |
+
+#### Signals
+
+| Property | Type | Description |
+| -------- | ------------- | ------------------------------------- |
+| `values` | `Signal` | Currently selected values as a signal |
+
+#### Methods
+
+| Method | Parameters | Description |
+| -------------------------- | --------------------------------- | ------------------------------------------ |
+| `scrollActiveItemIntoView` | `options?: ScrollIntoViewOptions` | Scrolls the active item into view |
+| `gotoFirst` | none | Navigates to the first item in the listbox |
+
+### Option Directive
+
+The `ngOption` directive marks an item within a listbox.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | --------- | ------- | ------------------------------------------------ |
+| `id` | `string` | auto | Unique identifier for the option |
+| `value` | `V` | - | The value associated with this option (required) |
+| `label` | `string` | - | Optional label for screen readers |
+| `disabled` | `boolean` | `false` | Whether this option is disabled |
+
+#### Signals
+
+| Property | Type | Description |
+| ---------- | ----------------- | ------------------------------- |
+| `selected` | `Signal` | Whether this option is selected |
+| `active` | `Signal` | Whether this option has focus |
+
+### Related patterns
+
+Listbox is used by these documented dropdown patterns:
+
+- **[Select](guide/aria/select)** - Single-selection dropdown pattern using readonly combobox + listbox
+- **[Multiselect](guide/aria/multiselect)** - Multiple-selection dropdown pattern using readonly combobox + listbox with `multi`
+- **[Autocomplete](guide/aria/autocomplete)** - Filterable dropdown pattern using combobox + listbox
+
+For complete dropdown patterns with trigger, popup, and overlay positioning, see those pattern guides instead of using listbox alone.
+
+
+
+
+
diff --git a/adev-ja/src/content/guide/aria/menu.md b/adev-ja/src/content/guide/aria/menu.md
index a73ecf0d45..444325cfd2 100644
--- a/adev-ja/src/content/guide/aria/menu.md
+++ b/adev-ja/src/content/guide/aria/menu.md
@@ -1,23 +1,258 @@
-
-
-
+
+
+## Overview
-
+Position the menu using the `contextmenu` event coordinates.
+
+### Standalone menu
+
+A standalone menu doesn't require a trigger and remains visible in the interface.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Standalone menus work well for always-visible action lists or navigation.
+
+### Disabled menu items
+
+Disable specific menu items using the `disabled` input. Control focus behavior with `softDisabled`.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+When `[softDisabled]="true"`, disabled items can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled items are skipped during keyboard navigation.
+
+## APIs
+
+### Menu
+
+The container directive for menu items.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| -------------- | --------- | ------- | ------------------------------------------------------------- |
+| `disabled` | `boolean` | `false` | Disables all items in the menu |
+| `wrap` | `boolean` | `true` | Whether keyboard navigation wraps at edges |
+| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable but not interactive |
+
+#### Methods
+
+| Method | Parameters | Description |
+| ---------------- | ---------- | ---------------------------------- |
+| `close` | none | Closes the menu |
+| `focusFirstItem` | none | Moves focus to the first menu item |
+
+### MenuBar
+
+A horizontal container for multiple menus.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| -------------- | --------- | ------- | ------------------------------------------------------------- |
+| `disabled` | `boolean` | `false` | Disables the entire menubar |
+| `wrap` | `boolean` | `true` | Whether keyboard navigation wraps at edges |
+| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable but not interactive |
+
+### MenuItem
+
+An individual item within a menu.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ------------ | --------- | ------- | ---------------------------------------------------- |
+| `value` | `any` | — | **Required.** Value for this item |
+| `disabled` | `boolean` | `false` | Disables this menu item |
+| `submenu` | `Menu` | — | Reference to a submenu |
+| `searchTerm` | `string` | `''` | Search term for typeahead (supports two-way binding) |
+
+#### Signals
+
+| Property | Type | Description |
+| ---------- | ----------------- | ------------------------------------------ |
+| `active` | `Signal` | Whether the item currently has focus |
+| `expanded` | `Signal` | Whether the submenu is expanded |
+| `hasPopup` | `Signal` | Whether the item has an associated submenu |
+
+NOTE: MenuItem does not expose public methods. Use the `submenu` input to associate submenus with menu items.
+
+### MenuTrigger
+
+A button or element that opens a menu.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| -------------- | --------- | ------- | ------------------------------------------ |
+| `menu` | `Menu` | — | **Required.** The menu to trigger |
+| `disabled` | `boolean` | `false` | Disables the trigger |
+| `softDisabled` | `boolean` | `true` | When `true`, disabled trigger is focusable |
+
+#### Signals
+
+| Property | Type | Description |
+| ---------- | ----------------- | ------------------------------------------ |
+| `expanded` | `Signal` | Whether the menu is currently open |
+| `hasPopup` | `Signal` | Whether the trigger has an associated menu |
-### Example with TailwindCSS
+#### Methods
-
+| Method | Parameters | Description |
+| -------- | ---------- | ---------------------------- |
+| `open` | none | Opens the menu |
+| `close` | none | Closes the menu |
+| `toggle` | none | Toggles the menu open/closed |
diff --git a/adev-ja/src/content/guide/aria/menubar.md b/adev-ja/src/content/guide/aria/menubar.md
new file mode 100644
index 0000000000..780d7af8b7
--- /dev/null
+++ b/adev-ja/src/content/guide/aria/menubar.md
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+## Overview
+
+The manubar is a horizontal navigation bar that provides persistent access to application menus. Menubars organize commands into logical categories like File, Edit, and View, helping users discover and execute application features through keyboard or mouse interaction.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Usage
+
+Menubars work well for organizing application commands into persistent, discoverable navigation.
+
+**Use menubars when:**
+
+- Building application command bars (such as File, Edit, View, Insert, Format)
+- Creating persistent navigation that stays visible across the interface
+- Organizing commands into logical top-level categories
+- Need horizontal menu navigation with keyboard support
+- Building desktop-style application interfaces
+
+**Avoid menubars when:**
+
+- Building dropdown menus for individual actions (use [Menu with trigger](guide/aria/menu) instead)
+- Creating context menus (use [Menu](guide/aria/menu) guide pattern)
+- Simple standalone action lists (use [Menu](guide/aria/menu) instead)
+- Mobile interfaces where horizontal space is limited
+- Navigation belongs in a sidebar or header navigation pattern
+
+## Features
+
+- **Horizontal navigation** - Left/Right arrow keys move between top-level categories
+- **Persistent visibility** - Always visible, not modal or dismissable
+- **Hover-to-open** - Submenus open on hover after first keyboard or click interaction
+- **Nested submenus** - Support multiple levels of menu depth
+- **Keyboard navigation** - Arrow keys, Enter/Space, Escape, and typeahead search
+- **Disabled states** - Disable entire menubar or individual items
+- **RTL support** - Automatic right-to-left language navigation
+
+## Examples
+
+### Basic menubar
+
+A menubar provides persistent access to application commands organized into top-level categories. Users navigate between categories with Left/Right arrows and open menus with Enter or Down arrow.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Press Right arrow to move between File, Edit, and View. Press Enter or Down arrow to open a menu and navigate submenu items with Up/Down arrows.
+
+### Disabled menubar items
+
+Disable specific menu items or the entire menubar to prevent interaction. Control whether disabled items can receive keyboard focus with the `softDisabled` input.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+When `[softDisabled]="true"` on the menubar, disabled items can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled items are skipped during keyboard navigation.
+
+### RTL support
+
+Menubars automatically adapt to right-to-left (RTL) languages. Arrow key navigation reverses direction, and submenus position on the left side.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The `dir="rtl"` attribute enables RTL mode. Left arrow moves right, Right arrow moves left, maintaining natural navigation for RTL language users.
+
+## APIs
+
+The menubar pattern uses directives from Angular's Aria library. See the [Menu guide](guide/aria/menu) for complete API documentation.
+
+### MenuBar
+
+The horizontal container for top-level menu items.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| -------------- | --------- | ------- | ------------------------------------------------------------- |
+| `disabled` | `boolean` | `false` | Disables the entire menubar |
+| `wrap` | `boolean` | `true` | Whether keyboard navigation wraps from last to first item |
+| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable but not interactive |
+
+See the [Menu API documentation](guide/aria/menu#apis) for complete details on all available inputs and signals.
+
+### MenuItem
+
+Individual items within the menubar. Same API as Menu - see [MenuItem](guide/aria/menu#menuitem).
+
+**Menubar-specific behavior:**
+
+- Left/Right arrows navigate between menubar items (vs Up/Down in vertical menus)
+- First keyboard interaction or click enables hover-to-open for submenus
+- Enter or Down arrow opens the submenu and focuses the first item
+- `aria-haspopup="menu"` indicates items with submenus
+
+### MenuTrigger
+
+Not typically used in menubars - MenuItem handles trigger behavior directly when it has an associated submenu. See [MenuTrigger](guide/aria/menu#menutrigger) for standalone menu trigger patterns.
diff --git a/adev-ja/src/content/guide/aria/multiselect.md b/adev-ja/src/content/guide/aria/multiselect.md
new file mode 100644
index 0000000000..dc27f4a676
--- /dev/null
+++ b/adev-ja/src/content/guide/aria/multiselect.md
@@ -0,0 +1,201 @@
+
+
+
+## Overview
+
+A pattern that combines readonly combobox with multi-enabled listbox to create multiple-selection dropdowns with keyboard navigation and screen reader support.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Usage
+
+The multiselect pattern works best when users need to choose multiple related items from a familiar set of options.
+
+Consider using this pattern when:
+
+- **Users need multiple selections** - Tags, categories, filters, or labels where multiple choices apply
+- **The option list is fixed** (fewer than 20 items) - Users can scan options without search
+- **Filtering content** - Multiple criteria can be active simultaneously
+- **Assigning attributes** - Labels, permissions, or features where multiple values make sense
+- **Related choices** - Options that logically work together (such as selecting multiple team members)
+
+Avoid this pattern when:
+
+- **Only single selection is needed** - Use the [Select pattern](guide/aria/select) for simpler single-choice dropdowns
+- **The list has more than 20 items with search needed** - Use the [Autocomplete pattern](guide/aria/autocomplete) with multiselect capability
+- **Most or all options will be selected** - A checklist pattern provides better visibility
+- **Choices are independent binary options** - Individual checkboxes communicate the choices more clearly
+
+## Features
+
+The multiselect pattern combines [Combobox](guide/aria/combobox) and [Listbox](guide/aria/listbox) directives to provide a fully accessible dropdown with:
+
+- **Keyboard Navigation** - Navigate options with arrow keys, toggle with Space, close with Escape
+- **Screen Reader Support** - Built-in ARIA attributes including aria-multiselectable
+- **Selection Count Display** - Shows compact "Item + 2 more" pattern for multiple selections
+- **Signal-Based Reactivity** - Reactive state management using Angular signals
+- **Smart Positioning** - CDK Overlay handles viewport edges and scrolling
+- **Persistent Selection** - Selected options remain visible with checkmarks after selection
+
+## Examples
+
+### Basic multiselect
+
+Users need to select multiple items from a list of options. A readonly combobox paired with a multi-enabled listbox provides familiar multiselect functionality with full accessibility support.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The `multi` attribute on `ngListbox` enables multiple selection. Press Space to toggle options, and the popup remains open for additional selections. The display shows the first selected item plus a count of remaining selections.
+
+### Multiselect with custom display
+
+Options often need visual indicators like icons or colors to help users identify choices. Custom templates within options allow rich formatting while the display value shows a compact summary.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Each option displays an icon alongside its label. The display value updates to show the first selection's icon and text, followed by a count of additional selections. Selected options show a checkmark for clear visual feedback.
+
+### Controlled selection
+
+Forms sometimes need to limit the number of selections or validate user choices. Programmatic control over selection enables these constraints while maintaining accessibility.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+This example limits selections to three items. When the limit is reached, unselected options become disabled, preventing additional selections. A message informs users about the constraint.
+
+## APIs
+
+The multiselect pattern uses the following directives from Angular's Aria library. See the full API documentation in the linked guides.
+
+### Combobox Directives
+
+The multiselect pattern uses `ngCombobox` with the `readonly` attribute to prevent text input while preserving keyboard navigation.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | --------- | ------- | ----------------------------------------- |
+| `readonly` | `boolean` | `false` | Set to `true` to create dropdown behavior |
+| `disabled` | `boolean` | `false` | Disables the entire multiselect |
+
+See the [Combobox API documentation](guide/aria/combobox#apis) for complete details on all available inputs and signals.
+
+### Listbox Directives
+
+The multiselect pattern uses `ngListbox` with the `multi` attribute for multiple selection and `ngOption` for each selectable item.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| -------- | --------- | ------- | ------------------------------------------ |
+| `multi` | `boolean` | `false` | Set to `true` to enable multiple selection |
+
+#### Model
+
+| Property | Type | Description |
+| -------- | ------- | ----------------------------------------- |
+| `values` | `any[]` | Two-way bindable array of selected values |
+
+When `multi` is true, users can select multiple options using Space to toggle selection. The popup remains open after selection, allowing additional choices.
+
+See the [Listbox API documentation](guide/aria/listbox#apis) for complete details on listbox configuration, selection modes, and option properties.
+
+### Positioning
+
+The multiselect pattern integrates with [CDK Overlay](api/cdk/overlay/CdkConnectedOverlay) for smart positioning. Use `cdkConnectedOverlay` to handle viewport edges and scrolling automatically.
diff --git a/adev-ja/src/content/guide/aria/overview.md b/adev-ja/src/content/guide/aria/overview.md
index 4b8755feb4..9f7fe72d67 100644
--- a/adev-ja/src/content/guide/aria/overview.md
+++ b/adev-ja/src/content/guide/aria/overview.md
@@ -1,41 +1,91 @@
-
+## What is Angular Aria?
+
+Building accessible components seems straightforward, but implementing them according to the W3 Accessibility Guidelines requires significant effort and accessibility expertise.
+
+Angular Aria is a collection of headless, accessible directives that implement common WAI-ARIA patterns. The directives handle keyboard interactions, ARIA attributes, focus management, and screen reader support. All you have to do is provide the HTML structure, CSS styling, and business logic!
+
## Installation
-
- ng add @angular/cdk
-
-
-## Catalog
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+```shell
+npm install @angular/aria
+```
+
+## Showcase
+
+For example, let's take a toolbar menu. While it may appear to be a "simple" row of buttons tied with specific logic, keyboard navigation and screen readers add a lot of unexpected complexity to those unfamiliar with accessibility.
+
+```
+
+
+
+```
+
+In this one scenario, developers need to consider:
+
+- **Keyboard navigation**. Users need to open the menu with Enter or Space, navigate options with arrow keys, select with Enter, and close with Escape.
+- **Screen readers** need to announce the menu's state, the number of options, and which option has focus.
+- **Focus management** needs to move logically between the trigger and menu items.
+- **Right-to-left languages** require the ability to navigate in reverse.
+
+## What's included?
+
+Angular Aria includes directives for common interactive patterns:
+
+| Component | Description |
+| --------------------------------------- | ---------------------------------------------------------------------- |
+| [Accordion](guide/aria/accordion) | Collapsible content panels that can expand individually or exclusively |
+| [Autocomplete](guide/aria/autocomplete) | Text input with filtered suggestions that appear as users type |
+| [Combobox](guide/aria/combobox) | Primitive directive that coordinates a text input with a popup |
+| [Grid](guide/aria/grid) | Two-dimensional data display with cell-by-cell keyboard navigation |
+| [Listbox](guide/aria/listbox) | Single or multi-select option lists with keyboard navigation |
+| [Menu](guide/aria/menu) | Dropdown menus with nested submenus and keyboard shortcuts |
+| [Multiselect](guide/aria/multiselect) | Multiple-selection dropdown pattern with compact display |
+| [Select](guide/aria/select) | Single-selection dropdown pattern with keyboard navigation |
+| [Tabs](guide/aria/tabs) | Tabbed interfaces with automatic or manual activation modes |
+| [Toolbar](guide/aria/toolbar) | Grouped sets of controls with logical keyboard navigation |
+| [Tree](guide/aria/tree) | Hierarchical lists with expand/collapse functionality |
+
+Each component includes comprehensive documentation, working examples, and API references.
+
+## When to use Angular Aria
+
+Angular Aria works well when you need accessible interactive components that are WCAG compliant with custom styling. Examples include:
+
+- **Building a design system** - Your team maintains a component library with specific visual standards that need accessible implementations
+- **Enterprise component libraries** - You're creating reusable components for multiple applications within an organization
+- **Custom brand requirements** - The interface needs to match precise design specifications that pre-styled component libraries cannot easily accommodate
+
+## When not to use Angular Aria
+
+Angular Aria might not fit every scenario:
+
+- **Pre-styled components** - If you need components that look complete without custom styling, use Angular Material instead
+- **Simple forms** - Native HTML form controls like and provide built-in accessibility for straightforward use cases
+- **Rapid prototyping** - When validating concepts quickly, pre-styled component libraries reduce initial development time
+
+## Next steps
+
+Explore the component guides to find the pattern that fits your needs:
+
+**Search and selection**
+
+- Autocomplete - Search and filter options as users type
+- Listbox - Select one or multiple items from a list
+- Select - Choose one option from a list of options
+- Multiselect - Choose one option from a list of options
+
+**Navigation and call to actions**
+
+- Menu - Action menus with optional nested submenus
+- Tabs - Switch between related content panels
+- Toolbar - Group related controls and actions
+
+**Content organization**
+
+- Accordion - Show and hide sections of content
+- Tree - Display hierarchical data structures
+ Data display
+- Grid - Navigate and interact with tabular data
diff --git a/adev-ja/src/content/guide/aria/select.md b/adev-ja/src/content/guide/aria/select.md
new file mode 100644
index 0000000000..fa7f431c4c
--- /dev/null
+++ b/adev-ja/src/content/guide/aria/select.md
@@ -0,0 +1,193 @@
+
+
+
+## Overview
+
+A pattern that combines readonly combobox with listbox to create single-selection dropdowns with keyboard navigation and screen reader support.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Usage
+
+The select pattern works best when users need to choose a single value from a familiar set of options.
+
+Consider using this pattern when:
+
+- **The option list is fixed** (fewer than 20 items) - Users can scan and choose without filtering
+- **Options are familiar** - Users recognize the choices without needing to search
+- **Forms need standard fields** - Country, state, category, or status selection
+- **Settings and configuration** - Dropdown menus for preferences or options
+- **Clear option labels** - Each choice has a distinct, scannable name
+
+Avoid this pattern when:
+
+- **The list has more than 20 items** - Use the [Autocomplete pattern](guide/aria/autocomplete) for better filtering
+- **Users need to search options** - [Autocomplete](guide/aria/autocomplete) provides text input and filtering
+- **Multiple selection is needed** - Use the [Multiselect pattern](guide/aria/multiselect) instead
+- **Very few options exist (2-3)** - Radio buttons provide better visibility of all choices
+
+## Features
+
+The select pattern combines [Combobox](guide/aria/combobox) and [Listbox](guide/aria/listbox) directives to provide a fully accessible dropdown with:
+
+- **Keyboard Navigation** - Navigate options with arrow keys, select with Enter, close with Escape
+- **Screen Reader Support** - Built-in ARIA attributes for assistive technologies
+- **Custom Display** - Show selected values with icons, formatting, or rich content
+- **Signal-Based Reactivity** - Reactive state management using Angular signals
+- **Smart Positioning** - CDK Overlay handles viewport edges and scrolling
+- **Bidirectional Text Support** - Automatically handles right-to-left (RTL) languages
+
+## Examples
+
+### Basic select
+
+Users need a standard dropdown to choose from a list of values. A readonly combobox paired with a listbox provides the familiar select experience with full accessibility support.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The `readonly` attribute on `ngCombobox` prevents text input while preserving keyboard navigation. Users interact with the dropdown using arrow keys and Enter, just like a native select element.
+
+### Select with custom display
+
+Options often need visual indicators like icons or badges to help users identify choices quickly. Custom templates within options allow rich formatting while maintaining accessibility.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Each option displays an icon alongside the label. The selected value updates to show the chosen option's icon and text, providing clear visual feedback.
+
+### Disabled select
+
+Selects can be disabled to prevent user interaction when certain form conditions aren't met. The disabled state provides visual feedback and prevents keyboard interaction.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+When disabled, the select shows a disabled visual state and blocks all user interaction. Screen readers announce the disabled state to assistive technology users.
+
+## APIs
+
+The select pattern uses the following directives from Angular's Aria library. See the full API documentation in the linked guides.
+
+### Combobox Directives
+
+The select pattern uses `ngCombobox` with the `readonly` attribute to prevent text input while preserving keyboard navigation.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | --------- | ------- | ----------------------------------------- |
+| `readonly` | `boolean` | `false` | Set to `true` to create dropdown behavior |
+| `disabled` | `boolean` | `false` | Disables the entire select |
+
+See the [Combobox API documentation](guide/aria/combobox#apis) for complete details on all available inputs and signals.
+
+### Listbox Directives
+
+The select pattern uses `ngListbox` for the dropdown list and `ngOption` for each selectable item.
+
+#### Model
+
+| Property | Type | Description |
+| -------- | ------- | ---------------------------------------------------------------------------- |
+| `values` | `any[]` | Two-way bindable array of selected values (contains single value for select) |
+
+See the [Listbox API documentation](guide/aria/listbox#apis) for complete details on listbox configuration, selection modes, and option properties.
+
+### Positioning
+
+The select pattern integrates with [CDK Overlay](api/cdk/overlay/CdkConnectedOverlay) for smart positioning. Use `cdkConnectedOverlay` to handle viewport edges and scrolling automatically.
diff --git a/adev-ja/src/content/guide/aria/tabs.md b/adev-ja/src/content/guide/aria/tabs.md
index d9f676714f..29a292c37b 100644
--- a/adev-ja/src/content/guide/aria/tabs.md
+++ b/adev-ja/src/content/guide/aria/tabs.md
@@ -1,23 +1,296 @@
-
-
-
+
+
+## Overview
-
+
+
+
+
+
+
+
-### Example with TailwindCSS
+
+
+
+
+
+
+
+
-
+## Usage
+
+Tabs work well for organizing related content into distinct sections where users switch between different views or categories.
+
+**Use tabs when:**
+
+- Organizing related content into distinct sections
+- Creating settings panels with multiple categories
+- Building documentation with multiple topics
+- Implementing dashboards with different views
+- Showing content where users need to switch contexts
+
+**Avoid tabs when:**
+
+- Building sequential forms or wizards (use a stepper pattern)
+- Navigating between pages (use router navigation)
+- Showing single content sections (no need for tabs)
+- Having more than 7-8 tabs (consider a different layout)
+
+## Features
+
+- **Selection modes** - Tabs activate automatically on focus or require manual activation
+- **Keyboard navigation** - Arrow keys, Home, and End for efficient tab navigation
+- **Orientation** - Horizontal or vertical tab list layouts
+- **Lazy content** - Tab panels render only when first activated
+- **Disabled tabs** - Disable individual tabs with focus management
+- **Focus modes** - Roving tabindex or activedescendant focus strategies
+- **RTL support** - Right-to-left language navigation
+
+## Examples
+
+### Selection follows focus
+
+When selection follows focus, tabs activate immediately as you navigate with arrow keys. This provides instant feedback and works well for lightweight content.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Set `[selectionMode]="'follow'"` on the tab list to enable this behavior.
+
+### Manual activation
+
+With manual activation, arrow keys move focus between tabs without changing the selected tab. Users press Space or Enter to activate the focused tab.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Use `[selectionMode]="'explicit'"` for heavy content panels to avoid unnecessary rendering.
+
+### Vertical tabs
+
+Arrange tabs vertically for interfaces like settings panels or navigation sidebars.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Set `[orientation]="'vertical'"` on the tab list. Navigation changes to Up/Down arrow keys.
+
+### Lazy content rendering
+
+Use the `ngTabContent` directive on an `ng-template` to defer rendering tab panels until they're first shown.
+
+```angular-html
+
+
+
Tab 1
+
Tab 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+By default, content remains in the DOM after the panel is hidden. Set `[preserveContent]="false"` to remove content when the panel is deactivated.
+
+### Disabled tabs
+
+Disable specific tabs to prevent user interaction. Control whether disabled tabs can receive keyboard focus.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+When `[softDisabled]="true"` on the tab list, disabled tabs can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled tabs are skipped during keyboard navigation.
+
+## APIs
+
+### Tabs
+
+The container directive that coordinates tab lists and panels.
+
+This directive has no inputs or outputs. It serves as the root container for `ngTabList`, `ngTab`, and `ngTabPanel` directives.
+
+### TabList
+
+The container for tab buttons that manages selection and keyboard navigation.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| --------------- | ---------------------------- | -------------- | ------------------------------------------------------------------ |
+| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Tab list layout direction |
+| `wrap` | `boolean` | `false` | Whether keyboard navigation wraps from last to first tab |
+| `softDisabled` | `boolean` | `true` | When `true`, disabled tabs are focusable but not activatable |
+| `selectionMode` | `'follow' \| 'explicit'` | `'follow'` | Whether tabs activate on focus or require explicit activation |
+| `selectedTab` | `any` | — | The value of the currently selected tab (supports two-way binding) |
+
+### Tab
+
+An individual tab button.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | --------- | ------- | --------------------------------------- |
+| `value` | `any` | — | **Required.** Unique value for this tab |
+| `disabled` | `boolean` | `false` | Disables this tab |
+
+#### Signals
+
+| Property | Type | Description |
+| ---------- | ----------------- | ------------------------------------- |
+| `selected` | `Signal` | Whether the tab is currently selected |
+| `active` | `Signal` | Whether the tab currently has focus |
+
+### TabPanel
+
+The content panel associated with a tab.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ----------------- | --------- | ------- | ---------------------------------------------------------- |
+| `value` | `any` | — | **Required.** Must match the `value` of the associated tab |
+| `preserveContent` | `boolean` | `true` | Whether to keep panel content in DOM after deactivation |
+
+#### Signals
+
+| Property | Type | Description |
+| --------- | ----------------- | -------------------------------------- |
+| `visible` | `Signal` | Whether the panel is currently visible |
+
+### TabContent
+
+A structural directive for lazy rendering tab panel content.
+
+This directive has no inputs, outputs, or methods. Apply it to an `ng-template` element inside a tab panel:
+
+```angular-html
+
+
+
+
+
+```
diff --git a/adev-ja/src/content/guide/aria/toolbar.md b/adev-ja/src/content/guide/aria/toolbar.md
index 9fd328563a..1684759c0c 100644
--- a/adev-ja/src/content/guide/aria/toolbar.md
+++ b/adev-ja/src/content/guide/aria/toolbar.md
@@ -1,23 +1,272 @@
-
-
-
-
-
+## Overview
+
+A container for grouping related controls and actions with keyboard navigation, commonly used for text formatting, toolbars, and command panels.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Usage
+
+Toolbar works best for grouping related controls that users access frequently. Consider using toolbar when:
+
+- **Multiple related actions** - You have several controls that perform related functions (like text formatting buttons)
+- **Keyboard efficiency matters** - Users benefit from quick keyboard navigation through arrow keys
+- **Grouped controls** - You need to organize controls into logical sections with separators
+- **Frequent access** - Controls are used repeatedly within a workflow
+
+Avoid toolbar when:
+
+- A simple button group is sufficient - For just 2-3 unrelated actions, individual buttons work better
+- Controls aren't related - Toolbar implies a logical grouping; unrelated controls confuse users
+- Complex nested navigation - Deep hierarchies are better served by menus or navigation components
+
+## Features
+
+Angular's toolbar provides a fully accessible toolbar implementation with:
+
+- **Keyboard Navigation** - Navigate widgets with arrow keys, activate with Enter or Space
+- **Screen Reader Support** - Built-in ARIA attributes for assistive technologies
+- **Widget Groups** - Organize related widgets like radio button groups or toggle button groups
+- **Flexible Orientation** - Horizontal or vertical layouts with automatic keyboard navigation
+- **Signal-Based Reactivity** - Reactive state management using Angular signals
+- **Bidirectional Text Support** - Automatically handles right-to-left (RTL) languages
+- **Configurable Focus** - Choose between wrapping navigation or hard stops at edges
+
+## Examples
+
+### Basic horizontal toolbar
+
+Horizontal toolbars organize controls from left to right, matching the common pattern in text editors and design tools. Arrow keys navigate between widgets, maintaining focus within the toolbar until users press Tab to move to the next page element.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Vertical toolbar
+
+Vertical toolbars stack controls top to bottom, useful for side panels or vertical command palettes. Up and down arrow keys navigate between widgets.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Widget groups
+
+Widget groups contain related controls that work together, like text alignment options or list formatting choices. Groups maintain their own internal state while participating in toolbar navigation.
+
+In the examples above, the alignment buttons are wrapped in `ngToolbarWidgetGroup` with `role="radiogroup"` to create a mutually exclusive selection group.
+
+The `multi` input controls whether multiple widgets within a group can be selected simultaneously:
+
+
+
+ Left
+ Center
+ Right
+
-
+
+ Bold
+ Italic
+ Underline
+
+
-
-
-
-
-
+### Disabled widgets
--->
+Toolbars support two disabled modes:
-### Example with TailwindCSS
+1. **Soft-disabled** widgets remain focusable but visually indicate they're unavailable
+2. **Hard-disabled** widgets are completely removed from keyboard navigation.
-
+By default, `softDisabled` is `true`, which allows disabled widgets to still receive focus. If you want to enable hard-disabled mode, set `[softDisabled]="false"` on the toolbar.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Right-to-left (RTL) support
+
+Toolbars automatically support right-to-left languages. Wrap the toolbar in a container with `dir="rtl"` to reverse the layout and keyboard navigation direction. Arrow key navigation adjusts automatically: left arrow moves to the next widget, right arrow to the previous.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## APIs
+
+### Toolbar Directive
+
+The `ngToolbar` directive provides the container for toolbar functionality.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| -------------- | ------------------------------ | -------------- | ------------------------------------------------------ |
+| `orientation` | `'vertical'` \| `'horizontal'` | `'horizontal'` | Whether toolbar is vertically or horizontally oriented |
+| `disabled` | `boolean` | `false` | Disables the entire toolbar |
+| `softDisabled` | `boolean` | `true` | Whether disabled items can receive focus |
+| `wrap` | `boolean` | `true` | Whether focus should wrap at the edges |
+
+### ToolbarWidget Directive
+
+The `ngToolbarWidget` directive marks an element as a navigable widget within the toolbar.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | --------- | ------- | ----------------------------------------------- |
+| `id` | `string` | auto | Unique identifier for the widget |
+| `disabled` | `boolean` | `false` | Disables the widget |
+| `value` | `V` | - | The value associated with the widget (required) |
+
+#### Signals
+
+| Property | Type | Description |
+| ---------- | ----------------- | ------------------------------------------- |
+| `active` | `Signal` | Whether the widget is currently focused |
+| `selected` | `Signal` | Whether the widget is selected (in a group) |
+
+### ToolbarWidgetGroup Directive
+
+The `ngToolbarWidgetGroup` directive groups related widgets together.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | --------- | ------- | ---------------------------------------- |
+| `disabled` | `boolean` | `false` | Disables all widgets in the group |
+| `multi` | `boolean` | `false` | Whether multiple widgets can be selected |
+
+### Related components
+
+Toolbar can contain various widget types including buttons, trees, and comboboxes. See individual component documentation for specific widget implementations.
+
+
+
+
+
diff --git a/adev-ja/src/content/guide/aria/tree.md b/adev-ja/src/content/guide/aria/tree.md
index f3c1fc81d1..4119a887d4 100644
--- a/adev-ja/src/content/guide/aria/tree.md
+++ b/adev-ja/src/content/guide/aria/tree.md
@@ -1,23 +1,230 @@
-
-
-
+
+
+## Overview
-
+## Usage
-### Example with TailwindCSS
+Trees work well for displaying hierarchical data where users need to navigate through nested structures.
-
+**Use trees when:**
+
+- Building file system navigation
+- Showing folder and document hierarchies
+- Creating nested menu structures
+- Displaying organization charts
+- Browsing hierarchical data
+- Implementing site navigation with nested sections
+
+**Avoid trees when:**
+
+- Displaying flat lists (use [Listbox](guide/aria/listbox) instead)
+- Showing data tables (use [Grid](guide/aria/grid) instead)
+- Creating simple dropdowns (use [Select](guide/aria/select) instead)
+- Building breadcrumb navigation (use breadcrumb patterns)
+
+## Features
+
+- **Hierarchical navigation** - Nested tree structure with expand and collapse functionality
+- **Selection modes** - Single or multi-selection with explicit or follow-focus behavior
+- **Selection follows focus** - Optional automatic selection when focus changes
+- **Keyboard navigation** - Arrow keys, Home, End, and type-ahead search
+- **Expand/collapse** - Right/Left arrows or Enter to toggle parent nodes
+- **Disabled items** - Disable specific nodes with focus management
+- **Focus modes** - Roving tabindex or activedescendant focus strategies
+- **RTL support** - Right-to-left language navigation
+
+## Examples
+
+### Navigation tree
+
+Use a tree for navigation where clicking items triggers actions rather than selecting them.
+
+
+
+
+
+
+
+
+
+
+
+Set `[nav]="true"` to enable navigation mode. This uses `aria-current` to indicate the current page instead of selection.
+
+### Single selection
+
+Enable single selection for scenarios where users choose one item from the tree.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leave `[multi]="false"` (the default) for single selection. Users press Space to select the focused item.
+
+### Multi-selection
+
+Allow users to select multiple items from the tree.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Set `[multi]="true"` on the tree. Users select items individually with Space or select ranges with Shift+Arrow keys.
+
+### Selection follows focus
+
+When selection follows focus, the focused item is automatically selected. This simplifies interaction for navigation scenarios.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Set `[selectionMode]="'follow'"` on the tree. Selection automatically updates as users navigate with arrow keys.
+
+### Disabled tree items
+
+Disable specific tree nodes to prevent interaction. Control whether disabled items can receive focus.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+When `[softDisabled]="true"` on the tree, disabled items can receive focus but cannot be activated or selected. When `[softDisabled]="false"`, disabled items are skipped during keyboard navigation.
+
+## APIs
+
+### Tree
+
+The container directive that manages hierarchical navigation and selection.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| --------------- | -------------------------------- | ------------ | ------------------------------------------------------------- |
+| `disabled` | `boolean` | `false` | Disables the entire tree |
+| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable but not interactive |
+| `multi` | `boolean` | `false` | Whether multiple items can be selected |
+| `selectionMode` | `'explicit' \| 'follow'` | `'explicit'` | Whether selection requires explicit action or follows focus |
+| `nav` | `boolean` | `false` | Whether the tree is in navigation mode (uses `aria-current`) |
+| `wrap` | `boolean` | `true` | Whether keyboard navigation wraps from last to first item |
+| `focusMode` | `'roving' \| 'activedescendant'` | `'roving'` | Focus strategy used by the tree |
+| `values` | `any[]` | `[]` | Selected item values (supports two-way binding) |
+
+#### Methods
+
+| Method | Parameters | Description |
+| ---------------- | ---------- | --------------------------------------------- |
+| `expandAll` | none | Expands all tree nodes |
+| `collapseAll` | none | Collapses all tree nodes |
+| `selectAll` | none | Selects all items (only in multi-select mode) |
+| `clearSelection` | none | Clears all selection |
+
+### TreeItem
+
+An individual node in the tree that can contain child nodes.
+
+#### Inputs
+
+| Property | Type | Default | Description |
+| ---------- | --------- | ------- | ------------------------------------------------------- |
+| `value` | `any` | — | **Required.** Unique value for this tree item |
+| `disabled` | `boolean` | `false` | Disables this item |
+| `expanded` | `boolean` | `false` | Whether the node is expanded (supports two-way binding) |
+
+#### Signals
+
+| Property | Type | Description |
+| ------------- | ----------------- | ------------------------------------ |
+| `selected` | `Signal` | Whether the item is selected |
+| `active` | `Signal` | Whether the item currently has focus |
+| `hasChildren` | `Signal` | Whether the item has child nodes |
+
+#### Methods
+
+| Method | Parameters | Description |
+| ---------- | ---------- | --------------------------- |
+| `expand` | none | Expands this node |
+| `collapse` | none | Collapses this node |
+| `toggle` | none | Toggles the expansion state |
+
+### TreeGroup
+
+A container for child tree items.
+
+This directive has no inputs, outputs, or methods. It serves as a container to organize child `ngTreeItem` elements:
+
+```angular-html
+
+ Parent Item
+
+
Child 1
+
Child 2
+
+
+```
diff --git a/adev-ja/src/content/guide/components/anatomy-of-components.en.md b/adev-ja/src/content/guide/components/anatomy-of-components.en.md
index e90ce36779..5a301b26aa 100644
--- a/adev-ja/src/content/guide/components/anatomy-of-components.en.md
+++ b/adev-ja/src/content/guide/components/anatomy-of-components.en.md
@@ -5,9 +5,9 @@ TIP: This guide assumes you've already read the [Essentials Guide](essentials).
Every component must have:
-* A TypeScript class with _behaviors_ such as handling user input and fetching data from a server
-* An HTML template that controls what renders into the DOM
-* A [CSS selector](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors) that defines how the component is used in HTML
+- A TypeScript class with _behaviors_ such as handling user input and fetching data from a server
+- An HTML template that controls what renders into the DOM
+- A [CSS selector](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors) that defines how the component is used in HTML
You provide Angular-specific information for a component by adding a `@Component` [decorator](https://www.typescriptlang.org/docs/handbook/decorators.html) on top of the TypeScript class:
@@ -58,7 +58,7 @@ Both `templateUrl` and `styleUrl` are relative to the directory in which the com
To use a component, [directive](guide/directives), or [pipe](guide/templates/pipes), you must add
it to the `imports` array in the `@Component` decorator:
-```angular-ts
+```ts
import {ProfilePhoto} from './profile-photo';
@Component({
@@ -70,7 +70,7 @@ import {ProfilePhoto} from './profile-photo';
export class UserProfile { }
```
-By default, Angular components are *standalone*, meaning that you can directly add them to the `imports` array of other components. Components created with an earlier version of Angular may instead specify `standalone: false` in their `@Component` decorator. For these components, you instead import the `NgModule` in which the component is defined. See the full [`NgModule` guide](guide/ngmodules) for details.
+By default, Angular components are _standalone_, meaning that you can directly add them to the `imports` array of other components. Components created with an earlier version of Angular may instead specify `standalone: false` in their `@Component` decorator. For these components, you instead import the `NgModule` in which the component is defined. See the full [`NgModule` guide](guide/ngmodules) for details.
Important: In Angular versions before 19.0.0, the `standalone` option defaults to `false`.
@@ -97,8 +97,8 @@ You show a component by creating a matching HTML element in the template of _oth
export class ProfilePhoto { }
@Component({
- imports: [ProfilePhoto],
- template: ``
+imports: [ProfilePhoto],
+template: ``
})
export class UserProfile { }
@@ -121,5 +121,4 @@ flowchart TD
E[UserBio]
```
-
This tree structure is important to understanding several other Angular concepts, including [dependency injection](guide/di) and [child queries](guide/components/queries).
diff --git a/adev-ja/src/content/guide/components/anatomy-of-components.md b/adev-ja/src/content/guide/components/anatomy-of-components.md
index 7685e7c9c5..eb9597a548 100644
--- a/adev-ja/src/content/guide/components/anatomy-of-components.md
+++ b/adev-ja/src/content/guide/components/anatomy-of-components.md
@@ -1,13 +1,13 @@
-TIP: このガイドでは、すでに[基本概念のガイド](essentials)を読んでいることを前提としています。Angularを初めて使う場合は、まずそちらをお読みください。
+TIP: このガイドでは、すでに[基本ガイド](essentials)を読んでいることを前提としています。Angularを初めて使う場合は、まずそちらをお読みください。
すべてのコンポーネントには次のものが必要です。
-* ユーザー入力の処理やサーバーからのデータ取得などの*動作*を定義するTypeScriptクラス
-* DOMにレンダリングされる内容を制御するHTMLテンプレート
-* HTMLでコンポーネントがどのように使用されるかを定義する[CSSセレクター](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors)
+- ユーザー入力の処理やサーバーからのデータ取得などの*動作*を定義するTypeScriptクラス
+- DOMにレンダリングされる内容を制御するHTMLテンプレート
+- HTMLでコンポーネントがどのように使用されるかを定義する[CSSセレクター](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors)
TypeScriptクラスの上部に `@Component` [デコレーター](https://www.typescriptlang.org/docs/handbook/decorators.html) を追加することで、コンポーネントにAngular固有の情報を与えます。
@@ -51,14 +51,14 @@ export class ProfilePhoto { }
`templateUrl`と`styleUrl`の両方は、コンポーネントが存在するディレクトリを基準とした相対パスです。
-## コンポーネントの使用
+## コンポーネントの使用 {#using-components}
-### `@Component`デコレーターでのインポート
+### `@Component`デコレーターでのインポート {#imports-in-the-component-decorator}
コンポーネント、[ディレクティブ](guide/directives)、または[パイプ](guide/templates/pipes)を使用するには、
`@Component`デコレーターの`imports`配列に追加する必要があります。
-```angular-ts
+```ts
import {ProfilePhoto} from './profile-photo';
@Component({
@@ -74,7 +74,7 @@ export class UserProfile { }
IMPORTANT: 19.0.0より前のAngularバージョンでは、`standalone`オプションはデフォルトで`false`です。
-### テンプレートでのコンポーネントの表示
+### テンプレートでのコンポーネントの表示 {#showing-components-in-a-template}
すべてのコンポーネントは[CSSセレクター](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors)を定義します。
@@ -97,8 +97,8 @@ _他の_コンポーネントのテンプレートで一致するHTML要素を
export class ProfilePhoto { }
@Component({
- imports: [ProfilePhoto],
- template: ``
+imports: [ProfilePhoto],
+template: ``
})
export class UserProfile { }
@@ -121,5 +121,4 @@ flowchart TD
E[UserBio]
```
-
このツリー構造は、[依存性の注入](guide/di)や[子クエリ](guide/components/queries)など、他のいくつかのAngularの概念を理解する上で重要です。
diff --git a/adev-ja/src/content/guide/components/content-projection.en.md b/adev-ja/src/content/guide/components/content-projection.en.md
index 7a5ae1a6f1..efa351cabf 100644
--- a/adev-ja/src/content/guide/components/content-projection.en.md
+++ b/adev-ja/src/content/guide/components/content-projection.en.md
@@ -18,7 +18,7 @@ export class CustomCard {/* ... */}
```angular-ts
@Component({
selector: 'custom-card',
- template: '
',
+ template: '
',
})
export class CustomCard {/* ... */}
```
@@ -177,7 +177,7 @@ elements that don't match one of the component's placeholders do not render into
## Fallback content
-Angular can show *fallback content* for a component's `` placeholder if that component doesn't have any matching child content. You can specify fallback content by adding child content to the `` element itself.
+Angular can show _fallback content_ for a component's `` placeholder if that component doesn't have any matching child content. You can specify fallback content by adding child content to the `` element itself.
```angular-html
diff --git a/adev-ja/src/content/guide/components/content-projection.md b/adev-ja/src/content/guide/components/content-projection.md
index b9b4b9b6e2..91c0900a00 100644
--- a/adev-ja/src/content/guide/components/content-projection.md
+++ b/adev-ja/src/content/guide/components/content-projection.md
@@ -1,6 +1,6 @@
# `ng-content` を使ったコンテンツの投影
-TIP: このガイドは、すでに [基本概念のガイド](essentials) を読んだことを前提としています。Angularを初めて使う場合は、まずそちらを読んでください。
+TIP: このガイドは、すでに [基本ガイド](essentials) を読んだことを前提としています。Angularを初めて使う場合は、まずそちらを読んでください。
多くの場合、さまざまな種類のコンテンツを格納するコンポーネントを作成する必要があります。
例えば、カスタムカードコンポーネントを作成したいとします。
@@ -13,12 +13,12 @@ TIP: このガイドは、すでに [基本概念のガイド](essentials) を
export class CustomCard {/* ... */}
```
-**``要素は、コンテンツを配置する場所を示すプレースホルダーとして使用できます。**:
+**``要素は、コンテンツを配置する場所を示すプレースホルダーとして使用できます**:
```angular-ts
@Component({
selector: 'custom-card',
- template: '
',
+ template: '
',
})
export class CustomCard {/* ... */}
```
@@ -73,7 +73,7 @@ Angularは常にレンダリングされたコンテンツのDOMノードをイ
その``プレースホルダが非表示であってもです。コンポーネントコンテンツの条件付きレンダリングについては
[テンプレートフラグメント](api/core/ng-template)を参照してください。
-## 複数のコンテンツプレースホルダー
+## 複数のコンテンツプレースホルダー {#multiple-content-placeholders}
Angularは、CSSセレクターに基づいて、複数の異なる要素を異なる``プレースホルダーへの投影をサポートしています。
上記のカードの例を拡張して、`select`属性を使用して、
@@ -175,7 +175,7 @@ export class App {}
コンポーネントに`select`属性を持たない``プレースホルダーが含まれていない場合、
コンポーネントのいずれかのプレースホルダーに一致しない要素はDOMにレンダリングされません。
-## フォールバックコンテンツ
+## フォールバックコンテンツ {#fallback-content}
Angularは、コンポーネントの``プレースホルダーに一致する子コンテンツがない場合、コンポーネントの``プレースホルダーに*フォールバックコンテンツ*を表示できます。``要素自体に子コンテンツを追加することで、フォールバックコンテンツを指定できます。
@@ -207,7 +207,7 @@ Angularは、コンポーネントの``プレースホルダーに
```
-## 投影のためのコンテンツのエイリアシング
+## 投影のためのコンテンツのエイリアシング {#aliasing-content-for-projection}
Angularは、任意の要素にCSSセレクターを指定できる特殊な属性`ngProjectAs`をサポートしています。
`ngProjectAs`を持つ要素が``プレースホルダーに対してチェックされると、
diff --git a/adev-ja/src/content/guide/components/host-elements.en.md b/adev-ja/src/content/guide/components/host-elements.en.md
index b9566e0bdc..38f5080b34 100644
--- a/adev-ja/src/content/guide/components/host-elements.en.md
+++ b/adev-ja/src/content/guide/components/host-elements.en.md
@@ -37,7 +37,7 @@ In the above example, `` is the host element of the `ProfilePhoto
## Binding to the host element
-A component can bind properties, attributes, and events to its host element. This behaves
+A component can bind properties, attributes, styles and events to its host element. This behaves
identically to bindings on elements inside the component's template, but instead defined with
the `host` property in the `@Component` decorator:
@@ -48,6 +48,7 @@ the `host` property in the `@Component` decorator:
'role': 'slider',
'[attr.aria-valuenow]': 'value',
'[class.active]': 'isActive()',
+ '[style.background]' : `hasError() ? 'red' : 'green'`,
'[tabIndex]': 'disabled ? -1 : 0',
'(keydown)': 'updateValue($event)',
},
@@ -56,6 +57,7 @@ export class CustomSlider {
value: number = 0;
disabled: boolean = false;
isActive = signal(false);
+ hasError = signal(false);
updateValue(event: KeyboardEvent) { /* ... */ }
/* ... */
@@ -69,7 +71,7 @@ decorator to class members.
`@HostBinding` lets you bind host properties and attributes to properties and getters:
-```angular-ts
+```ts
@Component({
/* ... */
})
@@ -98,8 +100,10 @@ export class CustomSlider {
}
```
-**Always prefer using the `host` property over `@HostBinding` and `@HostListener`.** These
+
+ **Always prefer using the `host` property over `@HostBinding` and `@HostListener`.** These
decorators exist exclusively for backwards compatibility.
+
## Binding collisions
@@ -126,3 +130,58 @@ In cases like this, the following rules determine which value wins:
- If both values are static, the instance binding wins.
- If one value is static and the other dynamic, the dynamic value wins.
- If both values are dynamic, the component's host binding wins.
+
+## Styling with CSS custom properties
+
+Developers often rely on [CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascading_variables/Using_CSS_custom_properties) to enable a flexible configuration of their component's styles.
+You can set such custom properties on a host element with a [style binding][style binding](guide/templates/binding#css-style-properties).
+
+```angular-ts
+@Component({
+ /* ... */
+ host: {
+ '[style.--my-background]': 'color()',
+ }
+})
+export class MyComponent {
+ color = signal('lightgreen');
+}
+```
+
+In this example, the `--my-background` CSS custom property is bound to the `color` signal. The value of the custom property will automatically update whenever the `color` signal changes. This will affect the current component and all its children that rely on this custom property.
+
+### Setting custom properties on children compoents
+
+Alternatively, it is also possible to set css custom properties on the host element of children components with a [style binding](guide/templates/binding#css-style-properties).
+
+```angular-ts
+@Component({
+ selector: 'my-component',
+ template: ``,
+})
+export class MyComponent {
+ color = signal('lightgreen');
+}
+```
+
+## Injecting host element attributes
+
+Components and directives can read static attributes from their host element by using `HostAttributeToken` together with the [`inject`](api/core/inject) function.
+
+```ts
+import { Component, HostAttributeToken, inject } from '@angular/core';
+
+@Component({
+ selector: 'app-button',
+ ...,
+})
+export class Button {
+ variation = inject(new HostAttributeToken('variation'));
+}
+```
+
+```angular-html
+Click me
+```
+
+HELPFUL: `HostAttributeToken` throws an error if the attribute is missing, unless the injection is marked as optional.
diff --git a/adev-ja/src/content/guide/components/host-elements.md b/adev-ja/src/content/guide/components/host-elements.md
index f9bfc65d93..2897367deb 100644
--- a/adev-ja/src/content/guide/components/host-elements.md
+++ b/adev-ja/src/content/guide/components/host-elements.md
@@ -1,6 +1,6 @@
# コンポーネントのホスト要素
-TIP: このガイドでは、既に[基本概念のガイド](essentials)を読んでいることを前提としています。Angularを初めて使用する場合は、まずこちらをお読みください。
+TIP: このガイドでは、既に[基本ガイド](essentials)を読んでいることを前提としています。Angularを初めて使用する場合は、まずこちらをお読みください。
Angularは、コンポーネントのセレクターに一致するすべてのHTML要素に対して、コンポーネントのインスタンスを作成します。
コンポーネントのセレクターに一致するDOM要素は、そのコンポーネントの**ホスト要素**です。
@@ -35,9 +35,9 @@ export class ProfilePhoto {}
上記の例では、``は`ProfilePhoto`コンポーネントのホスト要素です。
-## ホスト要素へのバインディング
+## ホスト要素へのバインディング {#binding-to-the-host-element}
-コンポーネントは、ホスト要素にプロパティ、属性、イベントをバインドできます。
+コンポーネントは、ホスト要素にプロパティ、属性、スタイル、イベントをバインドできます。
これは、コンポーネントのテンプレート内の要素のバインディングと同じように動作しますが、
`@Component`デコレーターの`host`プロパティで定義されます。
@@ -48,6 +48,7 @@ export class ProfilePhoto {}
'role': 'slider',
'[attr.aria-valuenow]': 'value',
'[class.active]': 'isActive()',
+ '[style.background]' : `hasError() ? 'red' : 'green'`,
'[tabIndex]': 'disabled ? -1 : 0',
'(keydown)': 'updateValue($event)',
},
@@ -56,20 +57,21 @@ export class CustomSlider {
value: number = 0;
disabled: boolean = false;
isActive = signal(false);
+ hasError = signal(false);
updateValue(event: KeyboardEvent) { /* ... */ }
/* ... */
}
```
-## `@HostBinding`および`@HostListener`デコレーター
+## `@HostBinding`および`@HostListener`デコレーター {#the-hostbinding-and-hostlistener-decorators}
クラスメンバーに`@HostBinding`および`@HostListener`デコレーターを適用することにより、
ホスト要素にバインドできます。
`@HostBinding`を使用すると、ホストのプロパティと属性を、プロパティとゲッターにバインドできます。
-```angular-ts
+```ts
@Component({
/* ... */
})
@@ -98,10 +100,12 @@ export class CustomSlider {
}
```
-**常に`@HostBinding`と`@HostListener`よりも`host`プロパティの使用を優先してください。**
+
+ **常に`@HostBinding`と`@HostListener`よりも`host`プロパティの使用を優先してください。**
これらのデコレーターは、下位互換性のためにのみ存在します。
+
-## バインディングの衝突
+## バインディングの衝突 {#binding-collisions}
テンプレートでコンポーネントを使用する場合、そのコンポーネントインスタンスの要素にバインディングを追加できます。
コンポーネントは、同じプロパティまたは属性に対するホストバインディングを定義することもあります。
@@ -126,3 +130,58 @@ export class ProfilePhoto { /* ... */ }
- 両方の値が静的な場合、インスタンスバインディングが優先されます。
- 一方の値が静的で他方が動的な場合、動的な値が優先されます。
- 両方の値が動的な場合、コンポーネントのホストバインディングが優先されます。
+
+## CSSカスタムプロパティを使用したスタイリング {#styling-with-css-custom-properties}
+
+開発者は、コンポーネントのスタイルを柔軟に設定できるようにするために、[CSSカスタムプロパティ](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascading_variables/Using_CSS_custom_properties)に頼ることがよくあります。
+このようなカスタムプロパティは、[スタイルバインディング](guide/templates/binding#css-style-properties)を使用してホスト要素に設定できます。
+
+```angular-ts
+@Component({
+ /* ... */
+ host: {
+ '[style.--my-background]': 'color()',
+ }
+})
+export class MyComponent {
+ color = signal('lightgreen');
+}
+```
+
+この例では、`--my-background` CSSカスタムプロパティが`color`シグナルにバインドされています。カスタムプロパティの値は、`color`シグナルが変更されるたびに自動的に更新されます。これは現在のコンポーネントと、このカスタムプロパティに依存するすべての子コンポーネントに影響します。
+
+### 子コンポーネントでのカスタムプロパティの設定 {#setting-custom-properties-on-children-compoents}
+
+また、[スタイルバインディング](guide/templates/binding#css-style-properties)を使用して、子コンポーネントのホスト要素にCSSカスタムプロパティを設定できます。
+
+```angular-ts
+@Component({
+ selector: 'my-component',
+ template: ``,
+})
+export class MyComponent {
+ color = signal('lightgreen');
+}
+```
+
+## ホスト要素の属性の注入 {#injecting-host-element-attributes}
+
+コンポーネントとディレクティブは、[`inject`](api/core/inject)関数とともに`HostAttributeToken`を使用して、ホスト要素から静的属性を読み取ることができます。
+
+```ts
+import { Component, HostAttributeToken, inject } from '@angular/core';
+
+@Component({
+ selector: 'app-button',
+ ...,
+})
+export class Button {
+ variation = inject(new HostAttributeToken('variation'));
+}
+```
+
+```angular-html
+Click me
+```
+
+HELPFUL: `HostAttributeToken`は、注入がオプションとしてマークされていない限り、属性が欠けている場合にエラーをスローします。
diff --git a/adev-ja/src/content/guide/components/inputs.en.md b/adev-ja/src/content/guide/components/inputs.en.md
index 77cceea06e..3f1df7bd43 100644
--- a/adev-ja/src/content/guide/components/inputs.en.md
+++ b/adev-ja/src/content/guide/components/inputs.en.md
@@ -7,15 +7,15 @@ TIP: If you're familiar with other web frameworks, input properties are similar
When you use a component, you commonly want to pass some data to it. A component specifies the data that it accepts by declaring
**inputs**:
-
+```ts {highlight:[5]}
import {Component, input} from '@angular/core';
-@Component({/*...*/})
+@Component({/_..._/})
export class CustomSlider {
// Declare an input named 'value' with a default value of zero.
value = input(0);
}
-
+```
This lets you bind to the property in a template:
@@ -25,7 +25,7 @@ This lets you bind to the property in a template:
If an input has a default value, TypeScript infers the type from the default value:
-```typescript
+```ts
@Component({/*...*/})
export class CustomSlider {
// TypeScript infers that this input is a number, returning InputSignal.
@@ -37,7 +37,7 @@ You can explicitly declare a type for the input by specifying a generic paramete
If an input without a default value is not set, its value is `undefined`:
-```typescript
+```ts
@Component({/*...*/})
export class CustomSlider {
// Produces an InputSignal because `value` may not be set.
@@ -57,18 +57,18 @@ When extending a component class, **inputs are inherited by the child class.**
The `input` function returns an `InputSignal`. You can read the value by calling the signal:
-
-import {Component, input} from '@angular/core';
+```ts {highlight:[5]}
+import {Component, input, computed} from '@angular/core';
-@Component({/*...*/})
+@Component({/_..._/})
export class CustomSlider {
- // Declare an input named 'value' with a default value of zero.
+ // Declare an input named 'value' with a default value of zero.
value = input(0);
// Create a computed expression that reads the value input
- label = computed(() => `The slider's value is ${this.value()}`);
+ label = computed(() => `The slider's value is ${this.value()}`);
}
-
+```
Signals created by the `input` function are read-only.
@@ -76,13 +76,13 @@ Signals created by the `input` function are read-only.
You can declare that an input is `required` by calling `input.required` instead of `input`:
-
+```ts {highlight:[3]}
@Component({/*...*/})
export class CustomSlider {
// Declare a required input named value. Returns an `InputSignal`.
value = input.required();
}
-
+```
Angular enforces that required inputs _must_ be set when the component is used in a template. If you try to use a component without specifying all of its required inputs, Angular reports an error at build-time.
@@ -96,7 +96,7 @@ The `input` function accepts a config object as a second parameter that lets you
You can specify a `transform` function to change the value of an input when it's set by Angular.
-
+```ts {highlight:[6]}
@Component({
selector: 'custom-slider',
/*...*/
@@ -108,7 +108,7 @@ export class CustomSlider {
function trimString(value: string | undefined): string {
return value?.trim() ?? '';
}
-
+```
```angular-html
@@ -126,7 +126,7 @@ The most common use-case for input transforms is to accept a wider range of valu
When you specify an input transform, the type of the transform function's parameter determines the types of values that can be set to the input in a template.
-
+```ts
@Component({/*...*/})
export class CustomSlider {
widthPx = input('', {transform: appendPx});
@@ -135,7 +135,7 @@ export class CustomSlider {
function appendPx(value: number): string {
return `${value}px`;
}
-
+```
In the example above, the `widthPx` input accepts a `number` while the `InputSignal` property returns a `string`.
@@ -143,15 +143,15 @@ In the example above, the `widthPx` input accepts a `number` while the `InputSig
Angular includes two built-in transform functions for the two most common scenarios: coercing values to boolean and numbers.
-
+```ts
import {Component, input, booleanAttribute, numberAttribute} from '@angular/core';
-@Component({/*...*/})
+@Component({/_..._/})
export class CustomSlider {
- disabled = input(false, {transform: booleanAttribute});
- value = input(0, {transform: numberAttribute});
+ disabled = input(false, {transform: booleanAttribute});
+ value = input(0, {transform: numberAttribute});
}
-
+```
`booleanAttribute` imitates the behavior of standard HTML [boolean attributes](https://developer.mozilla.org/docs/Glossary/Boolean/HTML), where the
_presence_ of the attribute indicates a "true" value. However, Angular's `booleanAttribute` treats the literal string `"false"` as the boolean `false`.
@@ -162,12 +162,12 @@ _presence_ of the attribute indicates a "true" value. However, Angular's `boolea
You can specify the `alias` option to change the name of an input in templates.
-
+```ts {highlight:[3]}
@Component({/*...*/})
export class CustomSlider {
value = input(0, {alias: 'sliderValue'});
}
-
+```
```angular-html
@@ -185,14 +185,14 @@ When creating a component, you can define a model input similarly to how you cre
Both types of input allow someone to bind a value into the property. However, **model inputs allow the component author to write values into the property**. If the property is bound with a two-way binding, the new value propagates to that binding.
-```typescript
+```ts
@Component({ /* ... */})
export class CustomSlider {
// Define a model input named "value".
value = model(0);
increment() {
- // Update the model input with a new value, propagating the value to any bindings.
+ // Update the model input with a new value, propagating the value to any bindings.
this.value.update(oldValue => oldValue + 10);
}
}
@@ -205,7 +205,7 @@ export class CustomSlider {
template: ``,
})
export class MediaControls {
- // Create a writable signal for the `volume` local state.
+ // Create a writable signal for the `volume` local state.
volume = signal(0);
}
```
@@ -220,7 +220,7 @@ See [Two-way binding](guide/templates/two-way-binding) for more details on two-w
You can bind a plain JavaScript property to a model input.
-```angular-ts
+```ts
@Component({
/* ... */
// `value` is a model input.
@@ -238,7 +238,7 @@ In the example above, the `CustomSlider` can write values into its `value` model
When you declare a model input in a component or directive, Angular automatically creates a corresponding [output](guide/components/outputs) for that model. The output's name is the model input's name suffixed with "Change".
-```angular-ts
+```ts
@Directive({ /* ... */ })
export class CustomCheckbox {
// This automatically creates an output named "checkedChange".
@@ -273,12 +273,12 @@ TIP: While the Angular team recommends using the signal-based `input` function f
You can alternatively declare component inputs by adding the `@Input` decorator to a property:
-
+```ts {highlight:[3]}
@Component({...})
export class CustomSlider {
@Input() value = 0;
}
-
+```
Binding to an input is the same in both signal-based and decorator-based inputs:
@@ -294,12 +294,12 @@ The `@Input` decorator accepts a config object that lets you change the way that
You can specify the `required` option to enforce that a given input must always have a value.
-
+```ts {highlight:[3]}
@Component({...})
export class CustomSlider {
@Input({required: true}) value = 0;
}
-
+```
If you try to use a component without specifying all of its required inputs, Angular reports an error at build-time.
@@ -307,7 +307,7 @@ If you try to use a component without specifying all of its required inputs, Ang
You can specify a `transform` function to change the value of an input when it's set by Angular. This transform function works identically to transform functions for signal-based inputs described above.
-
+```ts {highlight:[6]}
@Component({
selector: 'custom-slider',
...
@@ -316,19 +316,21 @@ export class CustomSlider {
@Input({transform: trimString}) label = '';
}
-function trimString(value: string | undefined) { return value?.trim() ?? ''; }
-
+function trimString(value: string | undefined) {
+ return value?.trim() ?? '';
+}
+```
#### Input aliases
You can specify the `alias` option to change the name of an input in templates.
-
+```ts {highlight:[3]}
@Component({...})
export class CustomSlider {
@Input({alias: 'sliderValue'}) value = 0;
}
-
+```
```angular-html
@@ -342,7 +344,7 @@ Input aliases work the same way as for signal-based inputs described above.
When using decorator-based inputs, a property implemented with a getter and setter can be an input:
-
+```ts
export class CustomSlider {
@Input()
get value(): number {
@@ -353,11 +355,11 @@ export class CustomSlider {
private internalValue = 0;
}
-
+```
You can even create a _write-only_ input by only defining a public setter:
-
+```ts
export class CustomSlider {
@Input()
set value(newValue: number) {
@@ -366,7 +368,7 @@ export class CustomSlider {
private internalValue = 0;
}
-
+```
**Prefer using input transforms instead of getters and setters** if possible.
@@ -376,22 +378,22 @@ Avoid complex or costly getters and setters. Angular may invoke an input's sette
In addition to the `@Input` decorator, you can also specify a component's inputs with the `inputs` property in the `@Component` decorator. This can be useful when a component inherits a property from a base class:
-
+```ts {highlight:[4]}
// `CustomSlider` inherits the `disabled` property from `BaseSlider`.
@Component({
...,
inputs: ['disabled'],
})
export class CustomSlider extends BaseSlider { }
-
+```
You can additionally specify an input alias in the `inputs` list by putting the alias after a colon in the string:
-
+```ts {highlight:[4]}
// `CustomSlider` inherits the `disabled` property from `BaseSlider`.
@Component({
...,
inputs: ['disabled: sliderDisabled'],
})
export class CustomSlider extends BaseSlider { }
-
+```
diff --git a/adev-ja/src/content/guide/components/inputs.md b/adev-ja/src/content/guide/components/inputs.md
index 6e71096c07..72d439abd5 100644
--- a/adev-ja/src/content/guide/components/inputs.md
+++ b/adev-ja/src/content/guide/components/inputs.md
@@ -7,15 +7,15 @@ TIP: 他のウェブフレームワークに精通している場合は、入力
コンポーネントを使用する際に、一般的にいくつかのデータを渡したいことがあります。
コンポーネントは、**入力**を宣言することで、受け入れるデータを指定します。
-
+```ts {highlight:[5]}
import {Component, input} from '@angular/core';
-@Component({/*...*/})
+@Component({/_..._/})
export class CustomSlider {
// Declare an input named 'value' with a default value of zero.
value = input(0);
}
-
+```
これにより、テンプレートのプロパティにバインドできます。
@@ -25,7 +25,7 @@ export class CustomSlider {
入力にデフォルト値がある場合、TypeScriptはデフォルト値から型を推論します。
-```typescript
+```ts
@Component({/*...*/})
export class CustomSlider {
// TypeScriptは、この入力が数値であると推論し、InputSignalを返します。
@@ -37,7 +37,7 @@ export class CustomSlider {
デフォルト値のない入力が設定されていない場合、その値は`undefined`になります。
-```typescript
+```ts
@Component({/*...*/})
export class CustomSlider {
// `value`は設定されない可能性があるため、InputSignalを生成します。
@@ -57,18 +57,18 @@ export class CustomSlider {
`input`関数は`InputSignal`を返します。シグナルを呼び出すことで値を読み取ることができます。
-
-import {Component, input} from '@angular/core';
+```ts {highlight:[5]}
+import {Component, input, computed} from '@angular/core';
-@Component({/*...*/})
+@Component({/_..._/})
export class CustomSlider {
- // Declare an input named 'value' with a default value of zero.
+ // Declare an input named 'value' with a default value of zero.
value = input(0);
// Create a computed expression that reads the value input
- label = computed(() => `The slider's value is ${this.value()}`);
+ label = computed(() => `The slider's value is ${this.value()}`);
}
-
+```
`input`関数によって作成されたシグナルは読み取り専用です。
@@ -76,13 +76,13 @@ export class CustomSlider {
`input`の代わりに`input.required`を呼び出すことで、入力が`required`であることを宣言できます。
-
+```ts {highlight:[3]}
@Component({/*...*/})
export class CustomSlider {
// Declare a required input named value. Returns an `InputSignal`.
value = input.required();
}
-
+```
Angularは、テンプレートでコンポーネントを使用する際に、必須入力が_必ず_設定されていることを強制します。すべての必須入力を指定せずにコンポーネントを使用しようとすると、Angularはビルド時にエラーを報告します。
@@ -96,7 +96,7 @@ Angularは、テンプレートでコンポーネントを使用する際に、
入力がAngularによって設定されるときに、その値を変更する`transform`関数を指定できます。
-
+```ts {highlight:[6]}
@Component({
selector: 'custom-slider',
/*...*/
@@ -108,7 +108,7 @@ export class CustomSlider {
function trimString(value: string | undefined): string {
return value?.trim() ?? '';
}
-
+```
```angular-html
@@ -143,15 +143,15 @@ function appendPx(value: number): string {
Angularには、最も一般的な2つのシナリオのための2つの組み込み変換関数が含まれています。ブール値と数値への値の強制変換です。
-
+```ts
import {Component, input, booleanAttribute, numberAttribute} from '@angular/core';
-@Component({/*...*/})
+@Component({/_..._/})
export class CustomSlider {
- disabled = input(false, {transform: booleanAttribute});
- value = input(0, {transform: numberAttribute});
+ disabled = input(false, {transform: booleanAttribute});
+ value = input(0, {transform: numberAttribute});
}
-
+```
`booleanAttribute`は、属性の_存在_が「true」値を示す標準的なHTML[ブール属性](https://developer.mozilla.org/docs/Glossary/Boolean/HTML)の動作を模倣します。
ただし、Angularの`booleanAttribute`は、リテラル文字列`"false"`をブール値`false`として扱います。
@@ -162,12 +162,12 @@ export class CustomSlider {
`alias`オプションを指定して、テンプレートでの入力の名前を変更できます。
-
+```ts {highlight:[3]}
@Component({/*...*/})
export class CustomSlider {
value = input(0, {alias: 'sliderValue'});
}
-
+```
```angular-html
@@ -185,7 +185,7 @@ export class CustomSlider {
どちらの種類の入力も、値をプロパティにバインドすることを可能にします。しかし、**モデル入力は、コンポーネントの作者がプロパティに値を書き込むことを可能にします。**プロパティが双方向バインディングでバインドされている場合、新しい値はそのバインディングに伝播します。
-```typescript
+```ts
@Component({ /* ... */})
export class CustomSlider {
// "value"という名前のモデル入力を定義します。
@@ -220,7 +220,7 @@ export class MediaControls {
プレーンなJavaScriptプロパティをモデル入力にバインドできます。
-```angular-ts
+```ts
@Component({
/* ... */
// `value`はモデル入力です。
@@ -238,7 +238,7 @@ export class MediaControls {
コンポーネントまたはディレクティブでモデル入力を宣言すると、Angularはそのモデルに対応する[出力](guide/components/outputs)を自動的に作成します。出力の名前は、モデル入力の名前に「Change」が付いたものです。
-```angular-ts
+```ts
@Directive({ /* ... */ })
export class CustomCheckbox {
// これにより、「checkedChange」という名前の出力が自動的に作成されます。
@@ -307,7 +307,7 @@ export class CustomSlider {
Angularによって入力が設定されるときにその値を変更する`transform`関数を指定できます。この変換関数は、上記で説明したシグナルベースの入力の変換関数と同様に機能します。
-
+```ts {highlight:[6]}
@Component({
selector: 'custom-slider',
...
@@ -316,19 +316,21 @@ export class CustomSlider {
@Input({transform: trimString}) label = '';
}
-function trimString(value: string | undefined) { return value?.trim() ?? ''; }
-
+function trimString(value: string | undefined) {
+ return value?.trim() ?? '';
+}
+```
#### 入力エイリアス
`alias`オプションを指定して、テンプレートでの入力の名前を変更できます。
-
+```ts {highlight:[3]}
@Component({...})
export class CustomSlider {
@Input({alias: 'sliderValue'}) value = 0;
}
-
+```
```angular-html
@@ -342,7 +344,7 @@ export class CustomSlider {
デコレーターベースの入力を使用する場合、ゲッターとセッターで実装されたプロパティを入力にできます。
-
+```ts
export class CustomSlider {
@Input()
get value(): number {
@@ -353,11 +355,11 @@ export class CustomSlider {
private internalValue = 0;
}
-
+```
パブリックセッターのみを定義することで、_書き込み専用_の入力を作成できます。
-
+```ts
export class CustomSlider {
@Input()
set value(newValue: number) {
@@ -366,7 +368,7 @@ export class CustomSlider {
private internalValue = 0;
}
-
+```
可能な場合は、**ゲッターとセッターの代わりに、入力変換を使用することをお勧めします。**
@@ -376,22 +378,22 @@ export class CustomSlider {
`@Input`デコレーターに加えて、`@Component`デコレーターの`inputs`プロパティを使用して、コンポーネントの入力を指定できます。これは、コンポーネントが基本クラスからプロパティを継承する場合に役立ちます。
-
+```ts {highlight:[4]}
// `CustomSlider` inherits the `disabled` property from `BaseSlider`.
@Component({
...,
inputs: ['disabled'],
})
export class CustomSlider extends BaseSlider { }
-
+```
文字列の後にコロンを付けてエイリアスを`inputs`リストに指定できます。
-
+```ts {highlight:[4]}
// `CustomSlider` inherits the `disabled` property from `BaseSlider`.
@Component({
...,
inputs: ['disabled: sliderDisabled'],
})
export class CustomSlider extends BaseSlider { }
-
+```
diff --git a/adev-ja/src/content/guide/components/lifecycle.en.md b/adev-ja/src/content/guide/components/lifecycle.en.md
index 09ae04a4ec..2d84280612 100644
--- a/adev-ja/src/content/guide/components/lifecycle.en.md
+++ b/adev-ja/src/content/guide/components/lifecycle.en.md
@@ -161,6 +161,12 @@ destroyed.
You can also use `DestroyRef` to keep setup code close to cleanup code, rather than putting
all cleanup code in the `ngOnDestroy` method.
+##### Detecting instance destruction
+
+`DestroyRef` provides a `destroyed` property that allows checking whether a given instance has already been destroyed. This is useful for avoiding operations on destroyed components, especially when dealing with delayed or asynchronous logic.
+
+By checking `destroyRef.destroyed`, you can prevent executing code after the instance has been cleaned up, avoiding potential errors such as `NG0911: View has already been destroyed.`.
+
### ngDoCheck
The `ngDoCheck` method runs before every time Angular checks a component's template for changes.
@@ -237,7 +243,7 @@ See [Using DOM APIs](guide/components/dom-apis) for guidance on working with the
Render callbacks do not run during server-side rendering or during build-time pre-rendering.
-#### after*Render phases
+#### after\*Render phases
When using `afterEveryRender` or `afterNextRender`, you can optionally split the work into phases. The
phase gives you control over the sequencing of DOM operations, letting you sequence _write_
diff --git a/adev-ja/src/content/guide/components/lifecycle.md b/adev-ja/src/content/guide/components/lifecycle.md
index d11f99c1e9..14e476bac2 100644
--- a/adev-ja/src/content/guide/components/lifecycle.md
+++ b/adev-ja/src/content/guide/components/lifecycle.md
@@ -161,6 +161,12 @@ export class UserProfile {
`DestroyRef` を使用して、クリーンアップコードをすべて `ngOnDestroy` メソッドに置くのではなく、
クリーンアップコードに近い場所にセットアップコードを保持できます。
+##### インスタンス破棄の検出
+
+`DestroyRef` は、指定されたインスタンスが既に破棄されているかどうかを確認できる `destroyed` プロパティを提供します。これは、特に遅延または非同期ロジックを扱う際に、破棄されたコンポーネントでの操作を避けるのに役立ちます。
+
+`destroyRef.destroyed` をチェックすることで、インスタンスがクリーンアップされた後にコードが実行されるのを防ぎ、`NG0911: View has already been destroyed.` などの潜在的なエラーを回避できます。
+
### ngDoCheck
`ngDoCheck` メソッドは、
@@ -237,7 +243,7 @@ AngularでDOMを操作する方法については、[DOM API の使用](guide/co
レンダリングコールバックは、サーバーサイドレンダリング中またはビルド時の事前レンダリング中は実行されません。
-#### afterEveryRender フェーズ
+#### after\*Render フェーズ
`afterEveryRender` または `afterNextRender` を使用する場合、
オプションで作業をフェーズに分割できます。
diff --git a/adev-ja/src/content/guide/components/outputs.en.md b/adev-ja/src/content/guide/components/outputs.en.md
index 16593b447f..57a302cc3e 100644
--- a/adev-ja/src/content/guide/components/outputs.en.md
+++ b/adev-ja/src/content/guide/components/outputs.en.md
@@ -4,12 +4,12 @@ TIP: This guide assumes you've already read the [Essentials Guide](essentials).
Angular components can define custom events by assigning a property to the `output` function:
-
+```ts {highlight:[3]}
@Component({/*...*/})
export class ExpandablePanel {
panelClosed = output();
}
-
+```
```angular-html
@@ -17,9 +17,9 @@ export class ExpandablePanel {
The `output` function returns an `OutputEmitterRef`. You can emit an event by calling the `emit` method on the `OutputEmitterRef`:
-
+```ts
this.panelClosed.emit();
-
+```
Angular refers to properties initialized with the `output` function as **outputs**. You can use outputs to raise custom events, similar to native browser events like `click`.
@@ -35,7 +35,7 @@ The `output` function has special meaning to the Angular compiler. **You can exc
You can pass event data when calling `emit`:
-
+```ts
// You can emit primitive values.
this.valueChanged.emit(7);
@@ -44,7 +44,7 @@ this.thumbDropped.emit({
pointerX: 123,
pointerY: 456,
})
-
+```
When defining an event listener in a template, you can access the event data from the `$event` variable:
@@ -54,7 +54,7 @@ When defining an event listener in a template, you can access the event data fro
Receive the event data in the parent component:
-
+```ts
@Component({
/*...*/
})
@@ -64,18 +64,18 @@ export class App {
}
}
-
+```
## Customizing output names
The `output` function accepts a parameter that lets you specify a different name for the event in a template:
-
+```ts
@Component({/*...*/})
export class CustomSlider {
changed = output({alias: 'valueChanged'});
}
-
+```
```angular-html
@@ -100,7 +100,7 @@ someComponentRef.instance.someEventProperty.subscribe(eventData => {
Angular automatically cleans up event subscriptions when it destroys components with subscribers. Alternatively, you can manually unsubscribe from an event. The `subscribe` function returns an `OutputRefSubscription` with an `unsubscribe` method:
-```typescript
+```ts
const eventSubscription = someComponent.someEventProperty.subscribe(eventData => {
console.log(eventData);
});
@@ -129,12 +129,12 @@ original decorator-based `@Output` API remains fully supported.
You can alternatively define custom events by assigning a property to a new `EventEmitter` and adding the `@Output` decorator:
-
+```ts
@Component({/*...*/})
export class ExpandablePanel {
@Output() panelClosed = new EventEmitter();
}
-
+```
You can emit an event by calling the `emit` method on the `EventEmitter`.
@@ -142,12 +142,12 @@ You can emit an event by calling the `emit` method on the `EventEmitter`.
The `@Output` decorator accepts a parameter that lets you specify a different name for the event in a template:
-
+```ts
@Component({/*...*/})
export class CustomSlider {
@Output('valueChanged') changed = new EventEmitter();
}
-
+```
```angular-html
@@ -159,22 +159,22 @@ This alias does not affect usage of the property in TypeScript code.
In addition to the `@Output` decorator, you can also specify a component's outputs with the `outputs` property in the `@Component` decorator. This can be useful when a component inherits a property from a base class:
-
+```ts
// `CustomSlider` inherits the `valueChanged` property from `BaseSlider`.
@Component({
/*...*/
outputs: ['valueChanged'],
})
export class CustomSlider extends BaseSlider {}
-
+```
You can additionally specify an output alias in the `outputs` list by putting the alias after a colon in the string:
-
+```ts
// `CustomSlider` inherits the `valueChanged` property from `BaseSlider`.
@Component({
/*...*/
outputs: ['valueChanged: volumeChanged'],
})
export class CustomSlider extends BaseSlider {}
-
+```
diff --git a/adev-ja/src/content/guide/components/outputs.md b/adev-ja/src/content/guide/components/outputs.md
index 45abffcf0d..e1941e6485 100644
--- a/adev-ja/src/content/guide/components/outputs.md
+++ b/adev-ja/src/content/guide/components/outputs.md
@@ -4,12 +4,12 @@ TIP: このガイドは、[基本概念のガイド](essentials) を既読して
Angularコンポーネントは、`output`関数にプロパティを割り当てることでカスタムイベントを定義できます。
-
+```ts {highlight:[3]}
@Component({/*...*/})
export class ExpandablePanel {
panelClosed = output();
}
-
+```
```angular-html
@@ -17,9 +17,9 @@ export class ExpandablePanel {
`output`関数は`OutputEmitterRef`を返します。`OutputEmitterRef`の`emit`メソッドを呼び出すことで、イベントを発生させることができます。
-
+```ts
this.panelClosed.emit();
-
+```
Angularでは、`output`関数で初期化されたプロパティを**出力**と呼びます。出力を使用すると、`click`などのネイティブブラウザイベントと同様に、カスタムイベントを発生させることができます。
@@ -35,7 +35,7 @@ Angularでは、`output`関数で初期化されたプロパティを**出力**
`emit`を呼び出す際に、イベントデータを渡すことができます。
-
+```ts
// プリミティブ値を送出できます。
this.valueChanged.emit(7);
@@ -44,7 +44,7 @@ this.thumbDropped.emit({
pointerX: 123,
pointerY: 456,
})
-
+```
テンプレートでイベントリスナーを定義する場合、`$event`変数からイベントデータにアクセスできます。
@@ -54,7 +54,7 @@ this.thumbDropped.emit({
親コンポーネントでイベントデータを受け取ります:
-
+```ts
@Component({
/*...*/
})
@@ -64,18 +64,18 @@ export class App {
}
}
-
+```
## 出力名のカスタマイズ
`output`関数は、テンプレートでイベントに異なる名前を指定できるパラメーターを受け入れます。
-
+```ts
@Component({/*...*/})
export class CustomSlider {
changed = output({alias: 'valueChanged'});
}
-
+```
```angular-html
@@ -100,7 +100,7 @@ someComponentRef.instance.someEventProperty.subscribe(eventData => {
Angularは、サブスクライバーを持つコンポーネントを破棄するときに、イベントサブスクリプションを自動的にクリーンアップします。または、イベントから手動で購読解除できます。`subscribe`関数は、`unsubscribe`メソッドを持つ`OutputRefSubscription`を返します。
-```typescript
+```ts
const eventSubscription = someComponent.someEventProperty.subscribe(eventData => {
console.log(eventData);
});
@@ -129,12 +129,12 @@ TIP: Angularチームは新規プロジェクトでは`output`関数の使用を
代替として、新しい`EventEmitter`にプロパティを割り当て、`@Output`デコレーターを追加することで、カスタムイベントを定義できます。
-
+```ts
@Component({/*...*/})
export class ExpandablePanel {
@Output() panelClosed = new EventEmitter();
}
-
+```
`EventEmitter`の`emit`メソッドを呼び出すことで、イベントを発生させることができます。
@@ -142,12 +142,12 @@ export class ExpandablePanel {
`@Output`デコレーターは、テンプレートでイベントに異なる名前を指定できるパラメーターを受け入れます。
-
+```ts
@Component({/*...*/})
export class CustomSlider {
@Output('valueChanged') changed = new EventEmitter();
}
-
+```
```angular-html
@@ -159,22 +159,22 @@ export class CustomSlider {
`@Output`デコレーターに加えて、`@Component`デコレーターの`outputs`プロパティを使用して、コンポーネントの出力を指定できます。これは、コンポーネントが基底クラスからプロパティを継承する場合に役立ちます。
-
+```ts
// `CustomSlider`は`BaseSlider`から`valueChanged`プロパティを継承します。
@Component({
/*...*/
outputs: ['valueChanged'],
})
export class CustomSlider extends BaseSlider {}
-
+```
`outputs`リストにエイリアスも指定できます。エイリアスは文字列の後にコロンを付けて記述します。
-
+```ts
// `CustomSlider`は`BaseSlider`から`valueChanged`プロパティを継承します。
@Component({
/*...*/
outputs: ['valueChanged: volumeChanged'],
})
export class CustomSlider extends BaseSlider {}
-
+```
diff --git a/adev-ja/src/content/guide/components/programmatic-rendering.en.md b/adev-ja/src/content/guide/components/programmatic-rendering.en.md
index 678d49dc21..51887ae359 100644
--- a/adev-ja/src/content/guide/components/programmatic-rendering.en.md
+++ b/adev-ja/src/content/guide/components/programmatic-rendering.en.md
@@ -2,16 +2,16 @@
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
-In addition to using a component directly in a template, you can also dynamically render components
-programmatically. This is helpful for situations when a component is unknown initially (thus can not
+In addition to using a component directly in a template, you can also dynamically render components
+programmatically. This is helpful for situations when a component is unknown initially (thus can not
be referenced in a template directly) and it depends on some conditions.
There are two main ways to render a component programmatically: in a template using `NgComponentOutlet`,
-or in your TypeScript code using `ViewContainerRef`.
+or in your TypeScript code using `ViewContainerRef`.
-HELPFUL: for lazy-loading use-cases (for example if you want to delay loading of a heavy component), consider
-using the built-in [`@defer` feature](/guide/templates/defer) instead. The `@defer` feature allows the code
-of any components, directives, and pipes inside the `@defer` block to be extracted into separate JavaScript
+HELPFUL: for lazy-loading use-cases (for example if you want to delay loading of a heavy component), consider
+using the built-in [`@defer` feature](/guide/templates/defer) instead. The `@defer` feature allows the code
+of any components, directives, and pipes inside the `@defer` block to be extracted into separate JavaScript
chunks automatically and loaded only when necessary, based on the configured triggers.
## Using NgComponentOutlet
@@ -103,10 +103,10 @@ In the example above, clicking the "Load content" button results in the followin
## Lazy-loading components
-HELPFUL: if you want to lazy-load some components, you may consider using the built-in [`@defer` feature](/guide/templates/defer)
+HELPFUL: if you want to lazy-load some components, you may consider using the built-in [`@defer` feature](/guide/templates/defer)
instead.
-If your use-case is not covered by the `@defer` feature, you can use either `NgComponentOutlet` or
+If your use-case is not covered by the `@defer` feature, you can use either `NgComponentOutlet` or
`ViewContainerRef` with a standard JavaScript [dynamic import](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import).
```angular-ts
@@ -119,9 +119,11 @@ If your use-case is not covered by the `@defer` feature, you can use either `NgC
Advanced settings
-
- Load advanced settings
-
+ @if(!advancedSettings) {
+
+ Load advanced settings
+
+ }
`
@@ -137,3 +139,117 @@ export class AdminSettings {
```
The example above loads and displays the `AdvancedSettings` upon receiving a button click.
+
+## Binding inputs, outputs and setting host directives at creation
+
+When dynamically creating components, manually setting inputs and subscribing to outputs can be error-prone. You often need to write extra code just to wire up bindings after the component is instantiated.
+
+To simplify this, both `createComponent` and `ViewContainerRef.createComponent` support passing a `bindings` array with helpers like `inputBinding()`, `outputBinding()`, and `twoWayBinding()` to configure inputs and outputs up front. You can also specify a `directives` array to apply any host directives. This enables creating components programmatically with template-like bindings in a single, declarative call.
+
+### Host view using `ViewContainerRef.createComponent`
+
+`ViewContainerRef.createComponent` creates a component and automatically inserts its host view and host element into the container’s view hierarchy at the container’s location. Use this when the dynamic component should become part of the container’s logical and visual structure (for example, adding list items or inline UI).
+
+By contrast, the standalone `createComponent` API does not attach the new component to any existing view or DOM location — it returns a `ComponentRef` and gives you explicit control over where to place the component’s host element.
+
+```angular-ts
+import { Component, input, model, output } from "@angular/core";
+
+@Component({
+ selector: 'app-warning',
+ template: `
+ @if(isExpanded()) {
+
+
Warning: Action needed!
+ Close
+
+ }
+ `
+})
+export class AppWarningComponent {
+ readonly canClose = input.required();
+ readonly isExpanded = model();
+ readonly close = output();
+}
+```
+
+```ts
+import { Component, ViewContainerRef, signal, inputBinding, outputBinding, twoWayBinding, inject } from '@angular/core';
+import { FocusTrap } from "@angular/cdk/a11y";
+import { ThemeDirective } from '../theme.directive';
+
+@Component({
+ template: ``
+})
+export class HostComponent {
+ private vcr = inject(ViewContainerRef);
+ readonly canClose = signal(true);
+ readonly isExpanded = signal(true);
+
+ showWarning() {
+ const compRef = this.vcr.createComponent(AppWarningComponent, {
+ bindings: [
+ inputBinding('canClose', this.canClose),
+ twoWayBinding('isExpanded', this.isExpanded),
+ outputBinding('close', (confirmed) => {
+ console.log('Closed with result:', confirmed);
+ })
+ ],
+ directives: [
+ FocusTrap,
+ { type: ThemeDirective, bindings: [inputBinding('theme', () => 'warning')] }
+ ]
+ });
+ }
+}
+```
+
+In the example above, the dynamic **AppWarningComponent** is created with its `canClose` input bound to a reactive signal, a two-way binding on its `isExpanded` state, and an output listener for `close`. The `FocusTrap` and `ThemeDirective` are attached to the host element via `directives`.
+
+### Popup attached to `document.body` with `createComponent` + `hostElement`
+
+Use this when rendering outside the current view hierarchy (e.g., overlays). The provided `hostElement` becomes the component’s host in the DOM, so Angular doesn’t create a new element matching the selector. Lets you configure **bindings** directly.
+
+```ts
+import {
+ ApplicationRef,
+ createComponent,
+ EnvironmentInjector,
+ inject,
+ Injectable,
+ inputBinding,
+ outputBinding,
+} from '@angular/core';
+import { PopupComponent } from './popup.component';
+
+@Injectable({ providedIn: 'root' })
+export class PopupService {
+ private readonly injector = inject(EnvironmentInjector);
+ private readonly appRef = inject(ApplicationRef);
+
+ show(message: string) {
+ // Create a host element for the popup
+ const host = document.createElement('popup-host');
+
+ // Create the component and bind in one call
+ const ref = createComponent(PopupComponent, {
+ environmentInjector: this.injector,
+ hostElement: host,
+ bindings: [
+ inputBinding('message', () => message),
+ outputBinding('closed', () => {
+ document.body.removeChild(host);
+ this.appRef.detachView(ref.hostView);
+ ref.destroy();
+ }),
+ ],
+ });
+
+ // Registers the component’s view so it participates in change detection cycle.
+ this.appRef.attachView(ref.hostView);
+ // Inserts the provided host element into the DOM (outside the normal Angular view hierarchy).
+ // This is what makes the popup visible on screen, typically used for overlays or modals.
+ document.body.appendChild(host);
+ }
+}
+```
diff --git a/adev-ja/src/content/guide/components/programmatic-rendering.md b/adev-ja/src/content/guide/components/programmatic-rendering.md
index b42de64bbe..1147946182 100644
--- a/adev-ja/src/content/guide/components/programmatic-rendering.md
+++ b/adev-ja/src/content/guide/components/programmatic-rendering.md
@@ -1,22 +1,23 @@
-# プログラムでコンポーネントをレンダリングする
+# コンポーネントのプログラマティックレンダリング
-TIP: このガイドでは、[基本概念のガイド](essentials)をすでに読んでいることを前提としています。Angularを初めて使用する場合は、まずこのガイドを読んでください。
+TIP: このガイドは、すでに[基本ガイド](essentials)を読んでいることを前提としています。Angularを初めて使う場合は、まずそちらをお読みください。
-コンポーネントはテンプレートで直接使用できるだけでなく、プログラムで動的にもレンダリングできます。
-これは、コンポーネントが最初は不明で(そのためテンプレートで直接参照できない)、何らかの条件に依存する場合に便利です。
+テンプレートでコンポーネントを直接使用する以外に、コンポーネントをプログラム的に動的にレンダリングできます。
+これは、コンポーネントが最初は不明で(したがってテンプレートで直接参照できない)、何らかの条件に依存する
+状況に役立ちます。
-コンポーネントをプログラムでレンダリングする主な方法は2つあります。
-テンプレートで`NgComponentOutlet`を使用するか、TypeScriptコードで`ViewContainerRef`を使用します。
+プログラム的にコンポーネントをレンダリングする主な方法は2つあります: テンプレートで`NgComponentOutlet`を使用する方法と、
+TypeScriptコードで`ViewContainerRef`を使用する方法です。
-HELPFUL: 遅延読み込みのユースケース(たとえば、重いコンポーネントの読み込みを遅らせたい場合)については、
-組み込みの[`@defer`機能](/guide/templates/defer)の使用を検討してください。`@defer`機能により、
-`@defer`ブロック内のコンポーネント、ディレクティブ、パイプのコードを自動的に別のJavaScriptチャンクに
-抽出し、設定されたトリガーに基づいて必要な時にのみ読み込むことができます。
+HELPFUL: 遅延読み込みのユースケース(たとえば、重いコンポーネントの読み込みを遅らせたい場合)については、代わりに組み込みの
+[`@defer`機能](/guide/templates/defer)の使用を検討してください。`@defer`機能を使用すると、`@defer`ブロック内のコンポーネント、ディレクティブ、パイプのコードが
+自動的に別のJavaScriptチャンクに抽出され、設定されたトリガーに基づいて必要な場合にのみ
+読み込まれます。
-## NgComponentOutletを使用する
+## NgComponentOutletの使用
-`NgComponentOutlet`は、
-テンプレートで指定されたコンポーネントを動的にレンダリングする構造ディレクティブです。
+`NgComponentOutlet`は、テンプレートで指定されたコンポーネントを動的にレンダリングする
+構造ディレクティブです。
```angular-ts
@Component({ ... })
@@ -40,18 +41,18 @@ export class CustomDialog {
}
```
-ディレクティブの機能の詳細については、
-[NgComponentOutlet APIリファレンス](api/common/NgComponentOutlet)を参照してください。
+ディレクティブの機能の詳細については、[NgComponentOutlet APIリファレンス](api/common/NgComponentOutlet)を
+参照してください。
-## ViewContainerRefを使用する
+## ViewContainerRefの使用
-**ビューコンテナ**は、Angularのコンポーネントツリー内のコンテンツを含むことができるノードです。
-どのコンポーネントまたはディレクティブでも`ViewContainerRef`を注入して、
-DOM内のそのコンポーネントまたはディレクティブの場所に対応するビューコンテナへの参照を取得できます。
+**ビューコンテナ**は、Angularのコンポーネントツリー内のノードで、コンテンツを含むことができます。任意のコンポーネント
+またはディレクティブは`ViewContainerRef`を注入して、DOM内のそのコンポーネントまたはディレクティブの位置に対応する
+ビューコンテナへの参照を取得できます。
-`ViewContainerRef`の`createComponent`メソッドを使用すると、コンポーネントを動的に作成してレンダリングできます。
-`ViewContainerRef`で新しいコンポーネントを作成すると、
-Angularはそのコンポーネントを、`ViewContainerRef`を注入したコンポーネントまたはディレクティブの次の兄弟としてDOMに追加します。
+`ViewContainerRef`の`createComponent`メソッドを使用して、コンポーネントを動的に作成およびレンダリングできます。
+`ViewContainerRef`で新しいコンポーネントを作成すると、Angularはそれを、`ViewContainerRef`を注入したコンポーネント
+またはディレクティブの次の兄弟としてDOMに追加します。
```angular-ts
@Component({
@@ -87,7 +88,7 @@ export class InnerItem {
}
```
-上記の例では、「コンテンツの読み込み」ボタンをクリックすると、次のDOM構造が生成されます。
+上記の例では、「Load content」ボタンをクリックすると、次のDOM構造になります
```angular-html
@@ -102,12 +103,10 @@ export class InnerItem {
## コンポーネントの遅延読み込み
-HELPFUL: いくつかのコンポーネントを遅延読み込みしたい場合は、
-組み込みの[`@defer`機能](/guide/templates/defer)の使用を検討してください。
+HELPFUL: コンポーネントを遅延読み込みしたい場合は、代わりに組み込みの[`@defer`機能](/guide/templates/defer)の使用を検討してください。
-あなたのユースケースが`@defer`機能でカバーされない場合は、
-`NgComponentOutlet`または`ViewContainerRef`を標準のJavaScript
-[動的インポート](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import)と一緒に使用できます。
+`@defer`機能でカバーされていないユースケースの場合は、標準のJavaScript [動的インポート](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import)と
+一緒に`NgComponentOutlet`または`ViewContainerRef`を使用できます。
```angular-ts
@Component({
@@ -119,9 +118,11 @@ HELPFUL: いくつかのコンポーネントを遅延読み込みしたい場
+ Close
+
+ }
+ `
+})
+export class AppWarningComponent {
+ readonly canClose = input.required();
+ readonly isExpanded = model();
+ readonly close = output();
+}
+```
+
+```ts
+import { Component, ViewContainerRef, signal, inputBinding, outputBinding, twoWayBinding, inject } from '@angular/core';
+import { FocusTrap } from "@angular/cdk/a11y";
+import { ThemeDirective } from '../theme.directive';
+
+@Component({
+ template: ``
+})
+export class HostComponent {
+ private vcr = inject(ViewContainerRef);
+ readonly canClose = signal(true);
+ readonly isExpanded = signal(true);
+
+ showWarning() {
+ const compRef = this.vcr.createComponent(AppWarningComponent, {
+ bindings: [
+ inputBinding('canClose', this.canClose),
+ twoWayBinding('isExpanded', this.isExpanded),
+ outputBinding('close', (confirmed) => {
+ console.log('Closed with result:', confirmed);
+ })
+ ],
+ directives: [
+ FocusTrap,
+ { type: ThemeDirective, bindings: [inputBinding('theme', () => 'warning')] }
+ ]
+ });
+ }
+}
+```
+
+上記の例では、動的な**AppWarningComponent**は、`canClose`インプットがリアクティブシグナルにバインドされ、`isExpanded`状態で双方向バインディングが行われ、`close`のアウトプットリスナーが設定されて作成されます。`FocusTrap`と`ThemeDirective`は、`directives`を介してホスト要素にアタッチされます。
+
+### `createComponent` + `hostElement`で`document.body`にアタッチされたポップアップ
+
+現在のビュー階層の外側にレンダリングする場合(オーバーレイなど)に使用します。提供された`hostElement`がDOM内のコンポーネントのホストになるため、Angularはセレクターに一致する新しい要素を作成しません。**bindings**を直接設定できます。
+
+```ts
+import {
+ ApplicationRef,
+ createComponent,
+ EnvironmentInjector,
+ inject,
+ Injectable,
+ inputBinding,
+ outputBinding,
+} from '@angular/core';
+import { PopupComponent } from './popup.component';
+
+@Injectable({ providedIn: 'root' })
+export class PopupService {
+ private readonly injector = inject(EnvironmentInjector);
+ private readonly appRef = inject(ApplicationRef);
+
+ show(message: string) {
+ // ポップアップ用のホスト要素を作成
+ const host = document.createElement('popup-host');
+
+ // コンポーネントを作成し、1回の呼び出しでバインド
+ const ref = createComponent(PopupComponent, {
+ environmentInjector: this.injector,
+ hostElement: host,
+ bindings: [
+ inputBinding('message', () => message),
+ outputBinding('closed', () => {
+ document.body.removeChild(host);
+ this.appRef.detachView(ref.hostView);
+ ref.destroy();
+ }),
+ ],
+ });
+
+ // 変更検知サイクルに参加するようにコンポーネントのビューを登録します。
+ this.appRef.attachView(ref.hostView);
+ // 提供されたホスト要素をDOM(通常のAngularビュー階層の外側)に挿入します。これにより、ポップアップが画面に表示されます。通常、オーバーレイやモーダルに使用されます。
+ document.body.appendChild(host);
+ }
+}
+```
+
diff --git a/adev-ja/src/content/guide/components/queries.en.md b/adev-ja/src/content/guide/components/queries.en.md
index 31b7374b7f..075d2c738a 100644
--- a/adev-ja/src/content/guide/components/queries.en.md
+++ b/adev-ja/src/content/guide/components/queries.en.md
@@ -15,7 +15,7 @@ There are two categories of query: **view queries** and **content queries.**
View queries retrieve results from the elements in the component's _view_ — the elements defined in the component's own template. You can query for a single result with the `viewChild` function.
-
+```typescript {highlight: [14, 15]}
@Component({
selector: 'custom-card-header',
/*...*/
@@ -32,7 +32,7 @@ export class CustomCard {
header = viewChild(CustomCardHeader);
headerText = computed(() => this.header()?.text);
}
-
+```
In this example, the `CustomCard` component queries for a child `CustomCardHeader` and uses the result in a `computed`.
@@ -40,7 +40,7 @@ If the query does not find a result, its value is `undefined`. This may occur if
You can also query for multiple results with the `viewChildren` function.
-
+```typescript {highlight: [17]}
@Component({
selector: 'custom-card-action',
/*...*/
@@ -51,8 +51,7 @@ export class CustomCardAction {
@Component({
selector: 'custom-card',
- template: `
- Save
+ template: `SaveCancel
`,
})
@@ -60,7 +59,7 @@ export class CustomCard {
actions = viewChildren(CustomCardAction);
actionsTexts = computed(() => this.actions().map(action => action.text);
}
-
+```
`viewChildren` creates a signal with an `Array` of the query results.
@@ -70,7 +69,7 @@ export class CustomCard {
Content queries retrieve results from the elements in the component's _content_— the elements nested inside the component in the template where it's used. You can query for a single result with the `contentChild` function.
-
+```typescript {highlight: [14, 15]}
@Component({
selector: 'custom-toggle',
/*...*/
@@ -81,26 +80,25 @@ export class CustomToggle {
@Component({
selector: 'custom-expando',
- /*...*/
+ /* ... */
})
export class CustomExpando {
toggle = contentChild(CustomToggle);
toggleText = computed(() => this.toggle()?.text);
}
-@Component({
- /* ... */
- // CustomToggle is used inside CustomExpando as content.
- template: `
+@Component({
+/* ... */
+// CustomToggle is used inside CustomExpando as content.
+template: `
Show
`
})
-export class UserProfile { }
-
-In this example, the `CustomExpando` component queries for a child `CustomToggle` and accesses the result in a `computed`.
+export class UserProfile { }
+```
If the query does not find a result, its value is `undefined`. This may occur if the target element is absent or hidden by `@if`. Angular keeps the result of `contentChild` up to date as your application state changes.
@@ -108,7 +106,7 @@ By default, content queries find only _direct_ children of the component and do
You can also query for multiple results with the `contentChildren` function.
-
+```typescript {highlight: [14, 16, 17, 18, 19, 20]}
@Component({
selector: 'custom-menu-item',
/*...*/
@@ -121,6 +119,7 @@ export class CustomMenuItem {
selector: 'custom-menu',
/*...*/
})
+
export class CustomMenu {
items = contentChildren(CustomMenuItem);
itemTexts = computed(() => this.items().map(item => item.text));
@@ -136,7 +135,7 @@ export class CustomMenu {
`
})
export class UserProfile { }
-
+```
`contentChildren` creates a signal with an `Array` of the query results.
@@ -146,7 +145,7 @@ export class UserProfile { }
If a child query (`viewChild` or `contentChild`) does not find a result, its value is `undefined`. This may occur if the target element is hidden by a control flow statement like `@if` or `@for`. Because of this, the child queries return a signal that include `undefined` in their value type.
-In some cases, especially with `viewChild`, you know with certainty that a specific child is always available. In other cases, you may want to strictly enforce that a specific child is present. For these cases, you can use a *required query*.
+In some cases, especially with `viewChild`, you know with certainty that a specific child is always available. In other cases, you may want to strictly enforce that a specific child is present. For these cases, you can use a _required query_.
```angular-ts
@Component({/* ... */})
@@ -216,6 +215,7 @@ All query functions accept an options object as a second parameter. These option
By default, the query locator indicates both the element you're searching for and the value retrieved. You can alternatively specify the `read` option to retrieve a different value from the element matched by the locator.
```ts
+
@Component({/*...*/})
export class CustomExpando {
toggle = contentChild(ExpandoContent, {read: TemplateRef});
@@ -230,9 +230,9 @@ Developers most commonly use `read` to retrieve `ElementRef` and `TemplateRef`.
### Content descendants
By default, `contentChildren` queries find only _direct_ children of the component and do not traverse into descendants.
-`contentChild` queries do traverse into descendants by default.
+`contentChild` queries do traverse into descendants by default.
-
+```typescript {highlight: [13, 14, 15, 16]}
@Component({
selector: 'custom-expando',
/*...*/
@@ -244,8 +244,7 @@ export class CustomExpando {
@Component({
selector: 'user-profile',
- template: `
-
+ template: ` Show
@@ -253,13 +252,14 @@ export class CustomExpando {
`
})
export class UserProfile { }
-
+```
In the example above, `CustomExpando` cannot find `` with `contentChildren` because it is not a direct child of ``. By setting `descendants: true`, you configure the query to traverse all descendants in the same template. Queries, however, _never_ pierce into components to traverse elements in other templates.
View queries do not have this option because they _always_ traverse into descendants.
## Decorator-based queries
+
TIP: While the Angular team recommends using the signal-based query function for new projects, the
original decorator-based query APIs remain fully supported.
@@ -269,7 +269,7 @@ You can alternatively declare queries by adding the corresponding decorator to a
You can query for a single result with the `@ViewChild` decorator.
-
+```typescript {highlight: [14, 16, 17, 18]}
@Component({
selector: 'custom-card-header',
/*...*/
@@ -289,7 +289,7 @@ export class CustomCard {
console.log(this.header.text);
}
}
-
+```
In this example, the `CustomCard` component queries for a child `CustomCardHeader` and accesses the result in `ngAfterViewInit`.
@@ -299,7 +299,7 @@ Angular keeps the result of `@ViewChild` up to date as your application state ch
You can also query for multiple results with the `@ViewChildren` decorator.
-
+```typescript {highlight: [17, 19, 20, 21, 22, 23]}
@Component({
selector: 'custom-card-action',
/*...*/
@@ -324,7 +324,7 @@ export class CustomCard {
});
}
}
-
+```
`@ViewChildren` creates a `QueryList` object that contains the query results. You can subscribe to changes to the query results over time via the `changes` property.
@@ -332,7 +332,7 @@ export class CustomCard {
You can query for a single result with the `@ContentChild` decorator.
-
+```typescript {highlight: [14, 16, 17, 18, 25]}
@Component({
selector: 'custom-toggle',
/*...*/
@@ -345,6 +345,7 @@ export class CustomToggle {
selector: 'custom-expando',
/*...*/
})
+
export class CustomExpando {
@ContentChild(CustomToggle) toggle: CustomToggle;
@@ -362,7 +363,7 @@ export class CustomExpando {
`
})
export class UserProfile { }
-
+```
In this example, the `CustomExpando` component queries for a child `CustomToggle` and accesses the result in `ngAfterContentInit`.
@@ -372,7 +373,7 @@ Angular keeps the result of `@ContentChild` up to date as your application state
You can also query for multiple results with the `@ContentChildren` decorator.
-
+```typescript {highlight: [15, 17, 18, 19, 20, 21]}
@Component({
selector: 'custom-menu-item',
/*...*/
@@ -385,6 +386,7 @@ export class CustomMenuItem {
selector: 'custom-menu',
/*...*/
})
+
export class CustomMenu {
@ContentChildren(CustomMenuItem) items: QueryList;
@@ -405,7 +407,7 @@ export class CustomMenu {
`
})
export class UserProfile { }
-
+```
`@ContentChildren` creates a `QueryList` object that contains the query results. You can subscribe to changes to the query results over time via the `changes` property.
diff --git a/adev-ja/src/content/guide/components/queries.md b/adev-ja/src/content/guide/components/queries.md
index baa7f164f8..4dfb5cff18 100644
--- a/adev-ja/src/content/guide/components/queries.md
+++ b/adev-ja/src/content/guide/components/queries.md
@@ -15,10 +15,10 @@ TIP: このガイドでは、[基本概念のガイド](essentials)を読んで
ビュークエリは、コンポーネントの_ビュー_(コンポーネント自身のテンプレートで定義された要素)内の要素から結果を取得します。`viewChild`関数を使用して単一の結果をクエリできます。
-
+```typescript {highlight: [14, 15]}
@Component({
selector: 'custom-card-header',
- /*...*/
+ /* ... */
})
export class CustomCardHeader {
text: string;
@@ -32,7 +32,7 @@ export class CustomCard {
header = viewChild(CustomCardHeader);
headerText = computed(() => this.header()?.text);
}
-
+```
この例では、`CustomCard`コンポーネントは子`CustomCardHeader`をクエリし、`computed`で結果を使用しています。
@@ -40,10 +40,10 @@ export class CustomCard {
`viewChildren`関数を使用して、複数結果をクエリできます。
-
+```typescript {highlight: [17]}
@Component({
selector: 'custom-card-action',
- /*...*/
+ /* ... */
})
export class CustomCardAction {
text: string;
@@ -51,8 +51,7 @@ export class CustomCardAction {
@Component({
selector: 'custom-card',
- template: `
- Save
+ template: `SaveCancel
`,
})
@@ -60,7 +59,7 @@ export class CustomCard {
actions = viewChildren(CustomCardAction);
actionsTexts = computed(() => this.actions().map(action => action.text);
}
-
+```
`viewChildren`は、クエリ結果の`Array`を含むシグナルを作成します。
@@ -70,10 +69,10 @@ export class CustomCard {
コンテンツクエリは、コンポーネントの_コンテンツ_(コンポーネントが使用されているテンプレート内でコンポーネントの中にネストされた要素)内の要素から結果を取得します。`contentChild`関数を使用して単一の結果をクエリできます。
-
+```typescript {highlight: [14, 15]}
@Component({
selector: 'custom-toggle',
- /*...*/
+ /* ... */
})
export class CustomToggle {
text: string;
@@ -81,26 +80,25 @@ export class CustomToggle {
@Component({
selector: 'custom-expando',
- /*...*/
+ /* ... */
})
export class CustomExpando {
toggle = contentChild(CustomToggle);
toggleText = computed(() => this.toggle()?.text);
}
-@Component({
- /* ... */
- // CustomToggle is used inside CustomExpando as content.
- template: `
+@Component({
+/* ... */
+// CustomToggle is used inside CustomExpando as content.
+template: `
Show
`
})
-export class UserProfile { }
-
-この例では、`CustomExpando`コンポーネントは子`CustomToggle`をクエリし、`computed`で結果にアクセスしています。
+export class UserProfile { }
+```
クエリが結果を見つけられない場合、その値は`undefined`になります。これは、ターゲット要素が存在しないか、`@if`によって非表示になっている場合に発生する可能性があります。Angularは、アプリケーションの状態が変化するにつれて`contentChild`の結果を最新の状態に保ちます。
@@ -108,10 +106,10 @@ export class UserProfile { }
`contentChildren`関数を使用して、複数結果をクエリできます。
-
+```typescript {highlight: [14, 16, 17, 18, 19, 20]}
@Component({
selector: 'custom-menu-item',
- /*...*/
+ /* ... */
})
export class CustomMenuItem {
text: string;
@@ -119,8 +117,9 @@ export class CustomMenuItem {
@Component({
selector: 'custom-menu',
- /*...*/
+ /* ... */
})
+
export class CustomMenu {
items = contentChildren(CustomMenuItem);
itemTexts = computed(() => this.items().map(item => item.text));
@@ -136,7 +135,7 @@ export class CustomMenu {
`
})
export class UserProfile { }
-
+```
`contentChildren`は、クエリ結果の`Array`を含むシグナルを作成します。
@@ -146,7 +145,7 @@ export class UserProfile { }
子クエリ(`viewChild`または`contentChild`)が結果を見つけられない場合、その値は`undefined`になります。これは、ターゲット要素が`@if`や`@for`などの制御フロー文によって非表示になっている場合に発生する可能性があります。このため、子クエリは`undefined`を含む値型を持つシグナルを返します。
-場合によっては、特に`viewChild`を使用する場合、特定の子が常に利用可能であることが確実な場合があります。他の場合では、特定の子が存在することを厳格に適用したい場合があります。これらの場合、*必須クエリ*を使用できます。
+場合によっては、特に`viewChild`を使用する場合、特定の子が常に利用可能であることが確実な場合があります。他の場合では、特定の子が存在することを厳格に適用したい場合があります。これらの場合、_必須クエリ_を使用できます。
```angular-ts
@Component({/* ... */})
@@ -216,6 +215,7 @@ export class CustomList {
デフォルトでは、クエリロケーターは、検索対象の要素と取得される値の両方を示します。代わりに、`read`オプションを指定して、ロケーターによって一致した要素から別の値を取得できます。
```ts
+
@Component({/*...*/})
export class CustomExpando {
toggle = contentChild(ExpandoContent, {read: TemplateRef});
@@ -229,13 +229,13 @@ export class CustomExpando {
### コンテンツの子孫
-デフォルトでは、`contentChildren`クエリはコンポーネントの直接の子要素のみを検索し、子孫要素にはトラバースしません。
+デフォルトでは、`contentChildren`クエリはコンポーネントの直接の子要素のみを検索し、子孫要素にはトラバースしません。
一方、`contentChild`クエリはデフォルトで子孫要素も検索します。
-
+```typescript {highlight: [13, 14, 15, 16]}
@Component({
selector: 'custom-expando',
- /*...*/
+ /* ... */
})
export class CustomExpando {
toggle = contentChildren(CustomToggle); // none found
@@ -244,8 +244,7 @@ export class CustomExpando {
@Component({
selector: 'user-profile',
- template: `
-
+ template: ` Show
@@ -253,13 +252,14 @@ export class CustomExpando {
`
})
export class UserProfile { }
-
+```
上記の例では、`CustomExpando` は `` の直接の子要素ではないため、`contentChildren` を用いると `` を検出できません。`descendants: true` を設定することで、同じテンプレート内のすべての子孫を対象にクエリを実行するように設定できます。ただし、クエリはコンポーネントの境界を越えて、他のテンプレートの要素にアクセスすることは _決して_ ありません。
ビュークエリにはこのオプションはありません。これは、常に子孫をトラバースするためです。
## デコレーターベースのクエリ
+
TIP: Angularチームは新規プロジェクトにはシグナルベースのクエリ関数の使用を推奨していますが、
元のデコレーターベースのクエリAPIは引き続き完全にサポートされています。
@@ -269,10 +269,10 @@ TIP: Angularチームは新規プロジェクトにはシグナルベースの
`@ViewChild`デコレーターを使用して、単一の結果をクエリできます。
-
+```typescript {highlight: [14, 16, 17, 18]}
@Component({
selector: 'custom-card-header',
- /*...*/
+ /* ... */
})
export class CustomCardHeader {
text: string;
@@ -289,7 +289,7 @@ export class CustomCard {
console.log(this.header.text);
}
}
-
+```
この例では、`CustomCard`コンポーネントは子`CustomCardHeader`をクエリし、`ngAfterViewInit`で結果にアクセスしています。
@@ -299,10 +299,10 @@ Angularは、アプリケーションの状態が変化するにつれて`@ViewC
`@ViewChildren`デコレーターを使用して、複数の結果をクエリできます。
-
+```typescript {highlight: [17, 19, 20, 21, 22, 23]}
@Component({
selector: 'custom-card-action',
- /*...*/
+ /* ... */
})
export class CustomCardAction {
text: string;
@@ -324,7 +324,7 @@ export class CustomCard {
});
}
}
-
+```
`@ViewChildren`は、クエリ結果を含む`QueryList`オブジェクトを作成します。`changes`プロパティを使用して、時間の経過とともにクエリ結果の変更を購読できます。
@@ -332,10 +332,10 @@ export class CustomCard {
`@ContentChild`デコレーターを使用して、単一の結果をクエリできます。
-
+```typescript {highlight: [14, 16, 17, 18, 25]}
@Component({
selector: 'custom-toggle',
- /*...*/
+ /* ... */
})
export class CustomToggle {
text: string;
@@ -343,8 +343,9 @@ export class CustomToggle {
@Component({
selector: 'custom-expando',
- /*...*/
+ /* ... */
})
+
export class CustomExpando {
@ContentChild(CustomToggle) toggle: CustomToggle;
@@ -362,7 +363,7 @@ export class CustomExpando {
`
})
export class UserProfile { }
-
+```
この例では、`CustomExpando`コンポーネントは子`CustomToggle`をクエリし、`ngAfterContentInit`で結果にアクセスしています。
@@ -372,10 +373,10 @@ Angularは、アプリケーションの状態が変化するにつれて`@Conte
`@ContentChildren`デコレーターを使用して、複数の結果をクエリできます。
-
+```typescript {highlight: [15, 17, 18, 19, 20, 21]}
@Component({
selector: 'custom-menu-item',
- /*...*/
+ /* ... */
})
export class CustomMenuItem {
text: string;
@@ -383,8 +384,9 @@ export class CustomMenuItem {
@Component({
selector: 'custom-menu',
- /*...*/
+ /* ... */
})
+
export class CustomMenu {
@ContentChildren(CustomMenuItem) items: QueryList;
@@ -405,7 +407,7 @@ export class CustomMenu {
`
})
export class UserProfile { }
-
+```
`@ContentChildren`は、クエリ結果を含む`QueryList`オブジェクトを作成します。`changes`プロパティを使用して、時間の経過とともにクエリ結果の変更を購読できます。
@@ -454,4 +456,3 @@ export class CustomCard {
子コンポーネントに直接状態を書き込むことは避けてください。このパターンは、理解しにくく、[ExpressionChangedAfterItHasBeenChecked](errors/NG0100)エラーが発生しやすい壊れやすいコードにつながる可能性があります。
親コンポーネントまたは祖先コンポーネントに直接状態を書き込むことは決してしないでください。このパターンは、理解しにくく、[ExpressionChangedAfterItHasBeenChecked](errors/NG0100)エラーが発生しやすい壊れやすいコードにつながる可能性があります。
-
diff --git a/adev-ja/src/content/guide/components/selectors.en.md b/adev-ja/src/content/guide/components/selectors.en.md
index acbb953e6f..b473b4d14a 100644
--- a/adev-ja/src/content/guide/components/selectors.en.md
+++ b/adev-ja/src/content/guide/components/selectors.en.md
@@ -120,7 +120,6 @@ default, the Angular CLI uses `app-`.
IMPORTANT: Angular uses the `ng` selector prefix for its own framework APIs. Never use `ng` as a selector prefix for your own custom components.
-
### When to use an attribute selector
You should consider an attribute selector when you want to create a component on a standard native
diff --git a/adev-ja/src/content/guide/components/selectors.md b/adev-ja/src/content/guide/components/selectors.md
index 44d03622cc..473c4edbc0 100644
--- a/adev-ja/src/content/guide/components/selectors.md
+++ b/adev-ja/src/content/guide/components/selectors.md
@@ -120,7 +120,6 @@ Angularチームは、プロジェクト内で定義されているすべての
IMPORTANT: Angularは、独自のフレームワークAPIに対して `ng` セレクタープレフィックスを使用します。独自のカスタムコンポーネントのセレクタープレフィックスとして `ng` を使用しないでください。
-
### 属性セレクターを使用する場合
標準のネイティブ要素にコンポーネントを作成する場合は、属性セレクターを検討する必要があります。
diff --git a/adev-ja/src/content/guide/components/styling.en.md b/adev-ja/src/content/guide/components/styling.en.md
index d2bdd219fe..9125127438 100644
--- a/adev-ja/src/content/guide/components/styling.en.md
+++ b/adev-ja/src/content/guide/components/styling.en.md
@@ -36,7 +36,7 @@ and [stylus](https://stylus-lang.com).
## Style scoping
Every component has a **view encapsulation** setting that determines how the framework scopes a
-component's styles. There are three view encapsulation modes: `Emulated`, `ShadowDom`, and `None`.
+component's styles. There are four view encapsulation modes: `Emulated`, `ShadowDom`, `ExperimentalIsolatedShadowDom`, and `None`.
You can specify the mode in the `@Component` decorator:
@@ -59,10 +59,11 @@ global styles defined outside of a component may still affect elements inside a
emulated encapsulation.
In emulated mode, Angular supports
-the [`:host`](https://developer.mozilla.org/docs/Web/CSS/:host)
-and [`:host-context()`](https://developer.mozilla.org/docs/Web/CSS/:host-context) pseudo
-classes without
-using [Shadow DOM](https://developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM).
+the [`:host`](https://developer.mozilla.org/docs/Web/CSS/:host) pseudo-class.
+While the [`:host-context()`](https://developer.mozilla.org/docs/Web/CSS/:host-context) pseudo-class
+is deprecated in modern browsers, Angular's compiler provides full support for it. Both pseudo-classes
+can be used without relying on native
+[Shadow DOM](https://developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM).
During compilation, the framework transforms these pseudo classes into attributes so it doesn't
comply with these native pseudo classes' rules at runtime (e.g. browser compatibility, specificity). Angular's
emulated encapsulation mode does not support any other pseudo classes related to Shadow DOM, such
@@ -82,9 +83,7 @@ using [the web standard Shadow DOM API](https://developer.mozilla.org/docs/Web/W
When enabling this mode, Angular attaches a shadow root to the component's host element and renders
the component's template and styles into the corresponding shadow tree.
-This mode strictly guarantees that _only_ that component's styles apply to elements in the
-component's template. Global styles cannot affect elements in a shadow tree and styles inside the
-shadow tree cannot affect elements outside of that shadow tree.
+Styles inside the shadow tree cannot affect elements outside of that shadow tree.
Enabling `ShadowDom` encapsulation, however, impacts more than style scoping. Rendering the
component in a shadow tree affects event propagation, interaction
@@ -92,6 +91,12 @@ with [the `` API](https://developer.mozilla.org/docs/Web/Web_Components/Us
and how browser developer tools show elements. Always understand the full implications of using
Shadow DOM in your application before enabling this option.
+### ViewEncapsulation.ExperimentalIsolatedShadowDom
+
+Behaves as above, except this mode strictly guarantees that _only_ that component's styles apply to elements in the
+component's template. Global styles cannot affect elements in a shadow tree and styles inside the
+shadow tree cannot affect elements outside of that shadow tree.
+
### ViewEncapsulation.None
This mode disables all style encapsulation for the component. Any styles associated with the
diff --git a/adev-ja/src/content/guide/components/styling.md b/adev-ja/src/content/guide/components/styling.md
index 2fec5b07aa..7f0e6f4d24 100644
--- a/adev-ja/src/content/guide/components/styling.md
+++ b/adev-ja/src/content/guide/components/styling.md
@@ -36,7 +36,7 @@ CSSを出力するすべてのツールと連携します。
## スタイルのスコープ
各コンポーネントには、**ビューカプセル化**設定があり、フレームワークがコンポーネントのスタイルをどのようにスコープするかを決定します。
-ビューカプセル化モードには、`Emulated`、`ShadowDom`、`None`の3つのモードがあります。
+ビューカプセル化モードには、`Emulated`、`ShadowDom`、`ExperimentalIsolatedShadowDom`、`None`の4つのモードがあります。
モードは、`@Component`デコレーターで指定できます。
@@ -59,13 +59,13 @@ export class ProfilePhoto { }
エミュレートされたカプセル化を持つコンポーネント内の要素に影響を与える可能性があります。
エミュレートされたモードでは、Angularは
-[`:host`](https://developer.mozilla.org/docs/Web/CSS/:host)
-および[`:host-context()`](https://developer.mozilla.org/docs/Web/CSS/:host-context)擬似
-クラスを、
-[Shadow DOM](https://developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM)
-を使用せずにサポートします。
-コンパイル時に、フレームワークはこれらの擬似クラスを属性に変換するため、実行時にこれらのネイティブ擬似クラスのルール(ブラウザの互換性、特異性など)に準拠しません。
-Angularのエミュレートされたカプセル化モードは、
+[`:host`](https://developer.mozilla.org/docs/Web/CSS/:host)擬似クラスをサポートします。
+[`:host-context()`](https://developer.mozilla.org/docs/Web/CSS/:host-context)擬似クラスは
+モダンブラウザでは非推奨ですが、Angularのコンパイラは完全にサポートします。これらの擬似クラスは
+ネイティブの[Shadow DOM](https://developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM)
+に依存せずに使用できます。
+コンパイル時に、フレームワークはこれらの擬似クラスを属性に変換するため、実行時にこれらのネイティブ擬似クラスのルール(ブラウザの互換性、特異性など)に準拠しません。Angularの
+エミュレートされたカプセル化モードは、
`::shadow`や`::part`など、Shadow DOMに関連するその他の擬似クラスをサポートしていません。
#### `::ng-deep`
@@ -82,7 +82,7 @@ Angularのエミュレートされたカプセル化モードは、カスタム
を使用して、コンポーネント内のスタイルをスコープします。
このモードを有効にすると、Angularはコンポーネントのホスト要素にシャドウルートを添付し、コンポーネントのテンプレートとスタイルを対応するシャドウツリーにレンダリングします。
-このモードでは、*そのコンポーネントのスタイルのみ*がコンポーネントのテンプレート内の要素に適用されることが厳密に保証されます。グローバルスタイルはシャドウツリー内の要素に影響を与えることができず、シャドウツリー内のスタイルはシャドウツリー外の要素に影響を与えることができません。
+シャドウツリー内のスタイルは、そのシャドウツリー外の要素に影響を与えることができません。
ただし、`ShadowDom`カプセル化を有効にすると、スタイルのスコープ以外にも影響があります。
シャドウツリーにコンポーネントをレンダリングすると、イベントの伝播、
@@ -90,6 +90,12 @@ Angularのエミュレートされたカプセル化モードは、カスタム
とのやり取り、ブラウザの開発者ツールによる要素の表示方法に影響を与えます。
このオプションを有効にする前に、アプリケーションでShadow DOMを使用することのすべての影響を理解してください。
+### ViewEncapsulation.ExperimentalIsolatedShadowDom
+
+上記と同様に動作しますが、このモードでは、_そのコンポーネントのスタイルのみ_が
+コンポーネントのテンプレート内の要素に適用されることが厳密に保証されます。グローバルスタイルはシャドウツリー内の要素に影響を与えることができず、シャドウツリー内の
+スタイルはシャドウツリー外の要素に影響を与えることができません。
+
### ViewEncapsulation.None
このモードは、コンポーネントのすべてのスタイルカプセル化を無効にします。
diff --git a/adev-ja/src/content/guide/di/creating-and-using-services.md b/adev-ja/src/content/guide/di/creating-and-using-services.md
new file mode 100644
index 0000000000..f8df5139a9
--- /dev/null
+++ b/adev-ja/src/content/guide/di/creating-and-using-services.md
@@ -0,0 +1,105 @@
+# Creating and using services
+
+Services are reusable pieces of code that can be shared across your Angular application. They typically handle data fetching, business logic, or other functionality that multiple components need to access.
+
+## Creating a service
+
+You can create a service with the [Angular CLI](tools/cli) with the following command:
+
+```bash
+ng generate service CUSTOM_NAME
+```
+
+This creates a dedicated `CUSTOM_NAME.ts` file in your `src` directory.
+
+You can also manually create a service by adding the `@Injectable()` decorator to a TypeScript class. This tells Angular that the service can be injected as a dependency.
+
+Here is an example of a service that allows users to add and request data:
+
+```ts
+// 📄 src/app/basic-data-store.ts
+import { Injectable } from '@angular/core';
+
+@Injectable({ providedIn: 'root' })
+export class BasicDataStore {
+ private data: string[] = []
+
+ addData(item: string): void {
+ this.data.push(item)
+ }
+
+ getData(): string[] {
+ return [...this.data]
+ }
+}
+```
+
+## How services become available
+
+When you use `@Injectable({ providedIn: 'root' })` in your service, Angular:
+
+- **Creates a single instance** (singleton) for your entire application
+- **Makes it available everywhere** without any additional configuration
+- **Enables tree-shaking** so the service is only included in your JavaScript bundle if it's actually used
+
+This is the recommended approach for most services.
+
+## Injecting a service
+
+Once you've created a service with `providedIn: 'root'`, you can inject it anywhere in your application using the `inject()` function from `@angular/core`.
+
+### Injecting into a component
+
+```angular-ts
+import { Component, inject } from '@angular/core';
+import { BasicDataStore } from './basic-data-store';
+
+@Component({
+ selector: 'app-example',
+ template: `
+
+
{{ dataStore.getData() }}
+
+ Add more data
+
+
+ `
+})
+export class ExampleComponent {
+ dataStore = inject(BasicDataStore);
+}
+```
+
+### Injecting into another service
+
+```ts
+import { inject, Injectable } from '@angular/core';
+import { AdvancedDataStore } from './advanced-data-store';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BasicDataStore {
+ private advancedDataStore = inject(AdvancedDataStore);
+ private data: string[] = [];
+
+ addData(item: string): void {
+ this.data.push(item);
+ }
+
+ getData(): string[] {
+ return [...this.data, ...this.advancedDataStore.getData()];
+ }
+}
+```
+
+## Next steps
+
+While `providedIn: 'root'` covers most use cases, Angular offers additional ways to provide services for specialized scenarios:
+
+- **Component-specific instances** - When components need their own isolated service instances
+- **Manual configuration** - For services that require runtime configuration
+- **Factory providers** - For dynamic service creation based on runtime conditions
+- **Value providers** - For providing configuration objects or constants
+
+You can learn more about these advanced patterns in the next guide: [defining dependency providers](/guide/di/defining-dependency-providers).
diff --git a/adev-ja/src/content/guide/di/creating-injectable-service.en.md b/adev-ja/src/content/guide/di/creating-injectable-service.en.md
deleted file mode 100644
index ca3a9bd49e..0000000000
--- a/adev-ja/src/content/guide/di/creating-injectable-service.en.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# Creating an injectable service
-
-Service is a broad category encompassing any value, function, or feature that an application needs.
-A service is typically a class with a narrow, well-defined purpose.
-A component is one type of class that can use DI.
-
-Angular distinguishes components from services to increase modularity and reusability.
-By separating a component's view-related features from other kinds of processing, you can make your component classes lean and efficient.
-
-Ideally, a component's job is to enable the user experience and nothing more.
-A component should present properties and methods for data binding, to mediate between the view (rendered by the template) and the application logic (which often includes some notion of a model).
-
-A component can delegate certain tasks to services, such as fetching data from the server, validating user input, or logging directly to the console.
-By defining such processing tasks in an injectable service class, you make those tasks available to any component.
-You can also make your application more adaptable by configuring different providers of the same kind of service, as appropriate in different circumstances.
-
-Angular does not enforce these principles.
-Angular helps you follow these principles by making it easy to factor your application logic into services and make those services available to components through DI.
-
-## Service examples
-
-Here's an example of a service class that logs to the browser console:
-
-
-export class Logger {
- log(msg: unknown) { console.log(msg); }
- error(msg: unknown) { console.error(msg); }
- warn(msg: unknown) { console.warn(msg); }
-}
-
-
-Services can depend on other services.
-For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes.
-That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server:
-
-
-import { inject } from "@angular/core";
-
-export class HeroService {
- private heroes: Hero[] = [];
-
- private backend = inject(BackendService);
- private logger = inject(Logger);
-
- async getHeroes() {
- // Fetch
- this.heroes = await this.backend.getAll(Hero);
- // Log
- this.logger.log(`Fetched ${this.heroes.length} heroes.`);
- return this.heroes;
- }
-}
-
-
-## Creating an injectable service with the CLI
-
-The Angular CLI provides a command to create a new service. In the following example, you add a new service to an existing application.
-
-To generate a new `HeroService` class in the `src/app/heroes` folder, follow these steps:
-
-1. Run this [Angular CLI](/tools/cli) command:
-
-
-ng generate service heroes/hero
-
-
-This command creates the following default `HeroService`:
-
-
-import { Injectable } from '@angular/core';
-
-@Injectable({
- providedIn: 'root',
-})
-export class HeroService {}
-
-
-The `@Injectable()` decorator specifies that Angular can use this class in the DI system.
-The metadata, `providedIn: 'root'`, means that the `HeroService` is provided throughout the application.
-
-Add a `getHeroes()` method that returns the heroes from `mock.heroes.ts` to get the hero mock data:
-
-
-import { Injectable } from '@angular/core';
-import { HEROES } from './mock-heroes';
-
-@Injectable({
- // declares that this service should be created
- // by the root application injector.
- providedIn: 'root',
-})
-export class HeroService {
- getHeroes() {
- return HEROES;
- }
-}
-
-
-For clarity and maintainability, it is recommended that you define components and services in separate files.
-
-## Injecting services
-
-To inject a service as a dependency into a component, you can declare a class field representing the dependency and use Angular's `inject` function to initialize it.
-
-The following example specifies the `HeroService` in the `HeroListComponent`.
-The type of `heroService` is `HeroService`.
-
-
-import { inject } from "@angular/core";
-
-export class HeroListComponent {
- private heroService = inject(HeroService);
-}
-
-
-It is also possible to inject a service into a component using the component's constructor:
-
-
- constructor(private heroService: HeroService)
-
-
-The `inject` method can be used in both classes and functions, while the constructor method can naturally only be used in a class constructor. However, in either case a dependency may only be injected in a valid [injection context](guide/di/dependency-injection-context), usually in the construction or initialization of a component.
-
-## Injecting services in other services
-
-When a service depends on another service, follow the same pattern as injecting into a component.
-In the following example, `HeroService` depends on a `Logger` service to report its activities:
-
-
-import { inject, Injectable } from '@angular/core';
-import { HEROES } from './mock-heroes';
-import { Logger } from '../logger.service';
-
-@Injectable({
- providedIn: 'root',
-})
-export class HeroService {
- private logger = inject(Logger);
-
- getHeroes() {
- this.logger.log('Getting heroes.');
- return HEROES;
- }
-}
-
-
-In this example, the `getHeroes()` method uses the `Logger` service by logging a message when fetching heroes.
-
-## What's next
-
-
-
-
-
diff --git a/adev-ja/src/content/guide/di/creating-injectable-service.md b/adev-ja/src/content/guide/di/creating-injectable-service.md
deleted file mode 100644
index 78379c75f8..0000000000
--- a/adev-ja/src/content/guide/di/creating-injectable-service.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# 注入可能なサービスの作成
-
-サービスとは、アプリケーションが必要とする値、関数、または機能を包括的に表すカテゴリーです。
-サービスは、通常、狭く明確に定義された目的を持つクラスです。
-コンポーネントは、DIを使用できるクラスの一種です。
-
-Angularは、モジュール性と再利用性を高めるために、コンポーネントとサービスを区別しています。
-コンポーネントのビュー関連の機能を他の処理から分離することで、コンポーネントクラスをスリムで効率的にできます。
-
-理想的には、コンポーネントの役割は、ユーザー体験を実現することだけです。
-コンポーネントは、データバインディング用のプロパティとメソッドを提供し、ビュー(テンプレートによってレンダリングされる)とアプリケーションロジック(多くの場合、モデルの概念が含まれる)の仲介役を果たすべきです。
-
-コンポーネントは、サーバーからのデータの取得、ユーザー入力の検証、またはコンソールへの直接ログ記録など、特定のタスクをサービスに委譲できます。
-このような処理タスクを注入可能サービスクラスで定義することで、これらのタスクをどのコンポーネントからも利用できるようになります。
-また、状況に応じて、同じ種類のサービスの異なるプロバイダーを構成することで、アプリケーションをより適応性高くできます。
-
-Angularは、これらの原則を強制しません。
-Angularは、アプリケーションロジックをサービスに分解し、それらのサービスをDIを介してコンポーネントに提供することを容易にすることで、これらの原則に従うように支援します。
-
-## サービスの例
-
-ブラウザコンソールにログ記録するサービスクラスの例を以下に示します。
-
-
-export class Logger {
- log(msg: unknown) { console.log(msg); }
- error(msg: unknown) { console.error(msg); }
- warn(msg: unknown) { console.warn(msg); }
-}
-
-
-サービスは、他のサービスに依存できます。
-たとえば、次の`HeroService`は`Logger`サービスに依存し、`BackendService`を使用してヒーローを取得します。
-そのサービスは、さらに`HttpClient`サービスに依存して、サーバーからヒーローを非同期に取得する場合があります。
-
-
-import { inject } from "@angular/core";
-
-export class HeroService {
- private heroes: Hero[] = [];
-
- private backend = inject(BackendService);
- private logger = inject(Logger);
-
- async getHeroes() {
- // Fetch
- this.heroes = await this.backend.getAll(Hero);
- // Log
- this.logger.log(`Fetched ${this.heroes.length} heroes.`);
- return this.heroes;
- }
-}
-
-
-## CLIでの注入可能なサービスの作成
-
-Angular CLIは、新しいサービスを作成するためのコマンドを提供します。
-次の例では、既存のアプリケーションに新しいサービスを追加します。
-
-`src/app/heroes`フォルダーに新しい`HeroService`クラスを生成するには、次の手順に従います。
-
-1. 次の[Angular CLI](/tools/cli)コマンドを実行します。
-
-
-ng generate service heroes/hero
-
-
-このコマンドは、次のデフォルトの`HeroService`を作成します。
-
-
-import { Injectable } from '@angular/core';
-
-@Injectable({
- providedIn: 'root',
-})
-export class HeroService {}
-
-
-`@Injectable()`デコレーターは、AngularがDIシステムでこのクラスを使用できることを指定します。
-メタデータ`providedIn: 'root'`は、`HeroService`がアプリケーション全体で提供されることを意味します。
-
-ヒーローのモックデータを取得するために、`mock.heroes.ts`からヒーローを返す`getHeroes()`メソッドを追加します。
-
-
-import { Injectable } from '@angular/core';
-import { HEROES } from './mock-heroes';
-
-@Injectable({
- // このサービスがルートアプリケーションインジェクターによって作成されることを宣言します。
- providedIn: 'root',
-})
-export class HeroService {
- getHeroes() {
- return HEROES;
- }
-}
-
-
-明確さと保守性の観点から、コンポーネントとサービスは別々のファイルに定義することをお勧めします。
-
-## サービスの注入
-
-コンポーネントに依存性としてサービスを注入するには、依存性を表すクラスフィールドを宣言し、Angularの`inject`関数を使用して初期化できます。
-
-次の例では、`HeroListComponent`内で`HeroService`を指定しています。
-`heroService`の型は`HeroService`です。
-
-
-import { inject } from "@angular/core";
-
-export class HeroListComponent {
- private heroService = inject(HeroService);
-}
-
-
-コンポーネントのコンストラクターを使用しても同様に、サービスをコンポーネントに注入できます:
-
-
- constructor(private heroService: HeroService)
-
-
-`inject`メソッドはクラスと関数の両方で使用できますが、コンストラクターメソッドは当然ながらクラスコンストラクターでのみ使用できます。ただし、いずれの場合も、依存性は通常コンポーネントの構築または初期化において、有効な[注入コンテキスト](guide/di/dependency-injection-context)でのみ注入できます。
-
-## 他のサービスでのサービスの注入
-
-サービスが別のサービスに依存する場合、コンポーネントへの注入と同じパターンに従います。
-次の例では、`HeroService`は`Logger`サービスに依存して、そのアクティビティを報告します。
-
-
-import { inject, Injectable } from '@angular/core';
-import { HEROES } from './mock-heroes';
-import { Logger } from '../logger.service';
-
-@Injectable({
- providedIn: 'root',
-})
-export class HeroService {
- private logger = inject(Logger);
-
- getHeroes() {
- this.logger.log('Getting heroes.');
- return HEROES;
- }
-}
-
-
-この例では、`getHeroes()`メソッドは、ヒーローを取得する際にメッセージをログ記録することで、`Logger`サービスを使用しています。
-
-## 次のステップ
-
-
-
-
-
diff --git a/adev-ja/src/content/guide/di/defining-dependency-providers.md b/adev-ja/src/content/guide/di/defining-dependency-providers.md
new file mode 100644
index 0000000000..3702715d59
--- /dev/null
+++ b/adev-ja/src/content/guide/di/defining-dependency-providers.md
@@ -0,0 +1,923 @@
+# Defining dependency providers
+
+Angular provides two ways to make services available for injection:
+
+1. **Automatic provision** - Using `providedIn` in the `@Injectable` decorator or by providing a factory in the `InjectionToken` configuration
+2. **Manual provision** - Using the `providers` array in components, directives, routes, or application config
+
+In the [previous guide](/guide/di/creating-and-using-services), you learned how to create services using `providedIn: 'root'`, which handles most common use cases. This guide explores additional patterns for both automatic and manual provider configuration.
+
+## Automatic provision for non-class dependencies
+
+While the `@Injectable` decorator with `providedIn: 'root'` works great for services (classes), you might need to provide other types of values globally - like configuration objects, functions, or primitive values. Angular provides `InjectionToken` for this purpose.
+
+### What is an InjectionToken?
+
+An `InjectionToken` is an object that Angular's dependency injection system uses to uniquely identify values for injection. Think of it as a special key that lets you store and retrieve any type of value in Angular's DI system:
+
+```ts
+import { InjectionToken } from '@angular/core';
+
+// Create a token for a string value
+export const API_URL = new InjectionToken('api.url');
+
+// Create a token for a function
+export const LOGGER = new InjectionToken<(msg: string) => void>('logger.function');
+
+// Create a token for a complex type
+export interface Config {
+ apiUrl: string;
+ timeout: number;
+}
+export const CONFIG_TOKEN = new InjectionToken('app.config');
+```
+
+NOTE: The string parameter (e.g., `'api.url'`) is a description purely for debugging — Angular identifies tokens by their object reference, not this string.
+
+### InjectionToken with `providedIn: 'root'`
+
+An `InjectionToken` that has a `factory` results in `providedIn: 'root'` by default (but can be overidden via the `providedIn` prop).
+
+```ts
+// 📁 /app/config.token.ts
+import { InjectionToken } from '@angular/core';
+
+export interface AppConfig {
+ apiUrl: string;
+ version: string;
+ features: Record;
+}
+
+// Globally available configuration using providedIn
+export const APP_CONFIG = new InjectionToken('app.config', {
+ providedIn: 'root',
+ factory: () => ({
+ apiUrl: 'https://api.example.com',
+ version: '1.0.0',
+ features: {
+ darkMode: true,
+ analytics: false
+ }
+ })
+});
+
+// No need to add to providers array - available everywhere!
+@Component({
+ selector: 'app-header',
+ template: `
Version: {{ config.version }}
`
+})
+export class HeaderComponent {
+ config = inject(APP_CONFIG); // Automatically available
+}
+```
+
+### When to use InjectionToken with factory functions
+
+InjectionToken with factory functions is ideal when you can't use a class but need to provide dependencies globally:
+
+```ts
+// 📁 /app/logger.token.ts
+import { InjectionToken, inject } from '@angular/core';
+import { APP_CONFIG } from './config.token';
+
+// Logger function type
+export type LoggerFn = (level: string, message: string) => void;
+
+// Global logger function with dependencies
+export const LOGGER_FN = new InjectionToken('logger.function', {
+ providedIn: 'root',
+ factory: () => {
+ const config = inject(APP_CONFIG);
+
+ return (level: string, message: string) => {
+ if (config.features.logging !== false) {
+ console[level](`[${new Date().toISOString()}] ${message}`);
+ }
+ };
+ }
+});
+
+// 📁 /app/storage.token.ts
+// Providing browser APIs as tokens
+export const LOCAL_STORAGE = new InjectionToken('localStorage', {
+ // providedIn: 'root' is configured as the default
+ factory: () => window.localStorage
+});
+
+export const SESSION_STORAGE = new InjectionToken('sessionStorage', {
+ providedIn: 'root',
+ factory: () => window.sessionStorage
+});
+
+// 📁 /app/feature-flags.token.ts
+// Complex configuration with runtime logic
+export const FEATURE_FLAGS = new InjectionToken
@@ -64,13 +31,13 @@ export class HighlightDirective {
The order of class declaration matters in TypeScript.
You can't refer directly to a class until it's been defined.
-This isn't usually a problem, especially if you adhere to the recommended *one class per file* rule.
+This isn't usually a problem, especially if you adhere to the recommended _one class per file_ rule.
But sometimes circular references are unavoidable.
For example, when class 'A' refers to class 'B' and 'B' refers to 'A', one of them has to be defined first.
-The Angular `forwardRef()` function creates an *indirect* reference that Angular can resolve later.
+The Angular `forwardRef()` function creates an _indirect_ reference that Angular can resolve later.
-You face a similar problem when a class makes *a reference to itself*.
+You face a similar problem when a class makes _a reference to itself_.
For example, in its `providers` array.
The `providers` array is a property of the `@Component()` decorator function, which must appear before the class definition.
You can break such circular references by using `forwardRef`.
diff --git a/adev-ja/src/content/guide/di/di-in-action.md b/adev-ja/src/content/guide/di/di-in-action.md
index caa5fa0842..a9d80c0ec3 100644
--- a/adev-ja/src/content/guide/di/di-in-action.md
+++ b/adev-ja/src/content/guide/di/di-in-action.md
@@ -2,42 +2,9 @@
このガイドでは、Angularにおける依存性の注入の追加機能について説明します。
-## `@Inject`を使用したカスタムプロバイダー
+NOTE: InjectionTokenとカスタムプロバイダーの包括的な説明については、[依存性プロバイダーの定義ガイド](guide/di/defining-dependency-providers#injection-tokens)を参照してください。
-カスタムプロバイダーを使用すると、組み込みのブラウザAPIなど、暗黙的な依存関係に対して具体的な実装を提供できます。
-次の例では、`InjectionToken`を使用して、`BrowserStorageService`内の依存関係として[localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)ブラウザAPIを提供します。
-
-
-import { Inject, Injectable, InjectionToken } from '@angular/core';
-
-export const BROWSER_STORAGE = new InjectionToken('Browser Storage', {
- providedIn: 'root',
- factory: () => localStorage
-});
-
-@Injectable({
- providedIn: 'root'
-})
-export class BrowserStorageService {
- public storage = inject(BROWSER_STORAGE);
-
- get(key: string) {
- return this.storage.getItem(key);
- }
-
- set(key: string, value: string) {
- this.storage.setItem(key, value);
- }
-}
-
-
-`factory`関数は、ブラウザのウィンドウオブジェクトに添付されている`localStorage`プロパティを返します。
-The `inject` function initializes the `storage` property with an instance of the token.
-
-このカスタムプロバイダーは、実際のブラウザAPIと対話するのではなく、モックAPIの`localStorage`を使用してテスト中にオーバーライドできます。
-
-## コンポーネントのDOM要素を注入する
+## コンポーネントのDOM要素を注入する {#inject-the-components-dom-element}
開発者は避けるように努めていても、一部の視覚効果とサードパーティツールでは、直接DOMにアクセスする必要があります。
そのため、コンポーネントのDOM要素にアクセスする必要がある場合があります。
@@ -48,29 +15,29 @@ Angularは、`@Component`または`@Directive`の基になる要素を、`Elemen
import { Directive, ElementRef } from '@angular/core';
@Directive({
- selector: '[appHighlight]'
+selector: '[appHighlight]'
})
export class HighlightDirective {
- private element = inject(ElementRef)
+private element = inject(ElementRef)
- update() {
- this.element.nativeElement.style.color = 'red';
- }
+update() {
+this.element.nativeElement.style.color = 'red';
+}
}
-## 前方参照を使用して循環した依存関係を解決する
+## 前方参照を使用して循環した依存関係を解決する {#resolve-circular-dependencies-with-a-forward-reference}
TypeScriptでは、クラスの宣言順序が重要です。
定義されるまでは、クラスを直接参照できません。
-これは、特に推奨される*1ファイルにつき1クラス*ルールに従っている場合は通常問題ありません。
+これは、特に推奨される_1ファイルにつき1クラス_ルールに従っている場合は通常問題ありません。
しかし、循環参照は避けられない場合があります。
たとえば、クラス'A'がクラス'B'を参照し、'B'が'A'を参照する場合、いずれか一方を最初に定義する必要があります。
-Angularの`forwardRef()`関数は、Angularが後で解決できる*間接的な*参照を作成します。
+Angularの`forwardRef()`関数は、Angularが後で解決できる_間接的な_参照を作成します。
-クラスが*自分自身を参照する*場合にも、同様の問題が発生します。
+クラスが_自分自身を参照する_場合にも、同様の問題が発生します。
たとえば、`providers`配列内です。
`providers`配列は、`@Component()`デコレーター関数のプロパティであり、クラス定義の前に表示される必要があります。
`forwardRef`を使用して、このような循環参照を解消できます。
diff --git a/adev-ja/src/content/guide/di/hierarchical-dependency-injection.en.md b/adev-ja/src/content/guide/di/hierarchical-dependency-injection.en.md
index 5cceb0196e..065a9a4aa7 100644
--- a/adev-ja/src/content/guide/di/hierarchical-dependency-injection.en.md
+++ b/adev-ja/src/content/guide/di/hierarchical-dependency-injection.en.md
@@ -1,23 +1,17 @@
# Hierarchical injectors
-Injectors in Angular have rules that you can leverage to achieve the desired visibility of injectables in your applications.
-By understanding these rules, you can determine whether to declare a provider at the application level, in a Component, or in a Directive.
+This guide provides in-depth coverage of Angular's hierarchical dependency injection system, including resolution rules, modifiers, and advanced patterns.
-The applications you build with Angular can become quite large, and one way to manage this complexity is to split up the application into a well-defined tree of components.
-
-There can be sections of your page that work in a completely independent way than the rest of the application, with its own local copies of the services and other dependencies that it needs.
-Some of the services that these sections of the application use might be shared with other parts of the application, or with parent components that are further up in the component tree, while other dependencies are meant to be private.
-
-With hierarchical dependency injection, you can isolate sections of the application and give them their own private dependencies not shared with the rest of the application, or have parent components share certain dependencies with its child components only but not with the rest of the component tree, and so on. Hierarchical dependency injection enables you to share dependencies between different parts of the application only when and if you need to.
+NOTE: For basic concepts about injector hierarchy and provider scoping, see the [defining dependency providers guide](guide/di/defining-dependency-providers#injector-hierarchy-in-angular).
## Types of injector hierarchies
Angular has two injector hierarchies:
-| Injector hierarchies | Details |
-|:--- |:--- |
-| `EnvironmentInjector` hierarchy | Configure an `EnvironmentInjector` in this hierarchy using `@Injectable()` or `providers` array in `ApplicationConfig`. |
-| `ElementInjector` hierarchy | Created implicitly at each DOM element. An `ElementInjector` is empty by default unless you configure it in the `providers` property on `@Directive()` or `@Component()`. |
+| Injector hierarchies | Details |
+| :------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `EnvironmentInjector` hierarchy | Configure an `EnvironmentInjector` in this hierarchy using `@Injectable()` or `providers` array in `ApplicationConfig`. |
+| `ElementInjector` hierarchy | Created implicitly at each DOM element. An `ElementInjector` is empty by default unless you configure it in the `providers` property on `@Directive()` or `@Component()`. |
For `NgModule` based applications, you can provide dependencies with the `ModuleInjector` hierarchy using an `@NgModule()` or `@Injectable()` annotation.
@@ -27,8 +21,8 @@ For `NgModule` based applications, you can provide dependencies with the `Module
The `EnvironmentInjector` can be configured in one of two ways by using:
-* The `@Injectable()` `providedIn` property to refer to `root` or `platform`
-* The `ApplicationConfig` `providers` array
+- The `@Injectable()` `providedIn` property to refer to `root` or `platform`
+- The `ApplicationConfig` `providers` array
@@ -42,17 +36,16 @@ Tree-shaking is especially useful for a library because the application which us
Provide services using `providedIn` of `@Injectable()` as follows:
-
+```ts {highlight:[4]}
import { Injectable } from '@angular/core';
@Injectable({
- providedIn: 'root' // <--provides this service in the root EnvironmentInjector
+ providedIn: 'root' // <--provides this service in the root EnvironmentInjector
})
export class ItemService {
name = 'telephone';
}
-
-
+```
The `@Injectable()` decorator identifies a service class.
The `providedIn` property configures a specific `EnvironmentInjector`, here `root`, which makes the service available in the `root` `EnvironmentInjector`.
@@ -61,8 +54,8 @@ The `providedIn` property configures a specific `EnvironmentInjector`, here `roo
In the case of `NgModule` based applications, the ModuleInjector can be configured in one of two ways by using:
-* The `@Injectable()` `providedIn` property to refer to `root` or `platform`
-* The `@NgModule()` `providers` array
+- The `@Injectable()` `providedIn` property to refer to `root` or `platform`
+- The `@NgModule()` `providers` array
`ModuleInjector` is configured by the `@NgModule.providers` and `NgModule.imports` property. `ModuleInjector` is a flattening of all the providers arrays that can be reached by following the `NgModule.imports` recursively.
@@ -74,9 +67,9 @@ There are two more injectors above `root`, an additional `EnvironmentInjector` a
Consider how Angular bootstraps the application with the following in `main.ts`:
-
+```ts
bootstrapApplication(AppComponent, appConfig);
-
+```
The `bootstrapApplication()` method creates a child injector of the platform injector which is configured by the `ApplicationConfig` instance.
This is the `root` `EnvironmentInjector`.
@@ -132,13 +125,13 @@ Angular creates `ElementInjector` hierarchies implicitly for each DOM element.
Providing a service in the `@Component()` decorator using its `providers` or `viewProviders` property configures an `ElementInjector`.
For example, the following `TestComponent` configures the `ElementInjector` by providing the service as follows:
-
+```ts {highlight:[3]}
@Component({
- …
+ /* … */
providers: [{ provide: ItemService, useValue: { name: 'lamp' } }]
})
export class TestComponent
-
+```
HELPFUL: See the [resolution rules](#resolution-rules) section to understand the relationship between the `EnvironmentInjector` tree, the `ModuleInjector` and the `ElementInjector` tree.
@@ -184,17 +177,17 @@ Import each of them from `@angular/core` and use each in the `inject` configurat
Resolution modifiers fall into three categories:
-* What to do if Angular doesn't find what you're looking for, that is `optional`
-* Where to start looking, that is `skipSelf`
-* Where to stop looking, `host` and `self`
+- What to do if Angular doesn't find what you're looking for, that is `optional`
+- Where to start looking, that is `skipSelf`
+- Where to stop looking, `host` and `self`
By default, Angular always starts at the current `Injector` and keeps searching all the way up.
Modifiers allow you to change the starting, or _self_, location and the ending location.
Additionally, you can combine all of the modifiers except:
-* `host` and `self`
-* `skipSelf` and `self`.
+- `host` and `self`
+- `skipSelf` and `self`.
### `optional`
@@ -202,11 +195,11 @@ Additionally, you can combine all of the modifiers except:
This way, if it can't be resolved at runtime, Angular resolves the service as `null`, rather than throwing an error.
In the following example, the service, `OptionalService`, isn't provided in the service, `ApplicationConfig`, `@NgModule()`, or component class, so it isn't available anywhere in the app.
-
+```ts {header:"src/app/optional/optional.component.ts"}
export class OptionalComponent {
public optional? = inject(OptionalService, {optional: true});
}
-
+```
### `self`
@@ -217,8 +210,7 @@ To avoid errors in this situation, combine `self` with `optional`.
For example, in the following `SelfNoDataComponent`, notice the injected `LeafService` as a property.
-
+```ts {header:"src/app/self-no-data/self-no-data.component.ts", highlight=[7]}>
@Component({
selector: 'app-self-no-data',
templateUrl: './self-no-data.component.html',
@@ -227,34 +219,43 @@ For example, in the following `SelfNoDataComponent`, notice the injected `LeafSe
export class SelfNoDataComponent {
public leaf = inject(LeafService, {optional: true, self: true});
}
-
+```
In this example, there is a parent provider and injecting the service will return the value, however, injecting the service with `self` and `optional` will return `null` because `self` tells the injector to stop searching in the current host element.
Another example shows the component class with a provider for `FlowerService`.
-In this case, the injector looks no further than the current `ElementInjector` because it finds the `FlowerService` and returns the tulip 🌷.
+In this case, the injector looks no further than the current `ElementInjector` because it finds the `FlowerService` and returns the tulip 🌷.
-
+```ts {header:"src/app/self/self.component.ts"}
+@Component({
+ selector: 'app-self',
+ templateUrl: './self.component.html',
+ styleUrls: ['./self.component.css'],
+ providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}],
+})
+export class SelfComponent {
+ constructor(@Self() public flower: FlowerService) {}
+}
+```
### `skipSelf`
`skipSelf` is the opposite of `self`.
With `skipSelf`, Angular starts its search for a service in the parent `ElementInjector`, rather than in the current one.
-So if the parent `ElementInjector` were using the fern 🌿 value for `emoji`, but you had maple leaf 🍁 in the component's `providers` array, Angular would ignore maple leaf 🍁 and use fern 🌿.
+So if the parent `ElementInjector` were using the fern 🌿 value for `emoji`, but you had maple leaf 🍁 in the component's `providers` array, Angular would ignore maple leaf 🍁 and use fern 🌿.
To see this in code, assume that the following value for `emoji` is what the parent component were using, as in this service:
-
+```ts {header:"src/app/leaf.service.ts"}
export class LeafService {
emoji = '🌿';
}
-
+```
-Imagine that in the child component, you had a different value, maple leaf 🍁 but you wanted to use the parent's value instead.
+Imagine that in the child component, you had a different value, maple leaf 🍁 but you wanted to use the parent's value instead.
This is when you'd use `skipSelf`:
-
+```ts {header:"src/app/skipself/skipself.component.ts" highlight:[[6],[10]]}
@Component({
selector: 'app-skipself',
templateUrl: './skipself.component.html',
@@ -266,9 +267,9 @@ export class SkipselfComponent {
// Use skipSelf as inject option
public leaf = inject(LeafService, {skipSelf: true});
}
-
+```
-In this case, the value you'd get for `emoji` would be fern 🌿, not maple leaf 🍁.
+In this case, the value you'd get for `emoji` would be fern 🌿, not maple leaf 🍁.
#### `skipSelf` option with `optional`
@@ -277,11 +278,11 @@ Use the `skipSelf` option with `optional` to prevent an error if the value is `n
In the following example, the `Person` service is injected during property initialization.
`skipSelf` tells Angular to skip the current injector and `optional` will prevent an error should the `Person` service be `null`.
-
+```ts
class Person {
parent = inject(Person, {optional: true, skipSelf: true})
}
-
+```
### `host`
@@ -292,34 +293,33 @@ class Person {
Even if there is a service instance further up the tree, Angular won't continue looking.
Use `host` as follows:
-
+```ts {header:"src/app/host/host.component.ts" highlight:[[6],[10]]}
@Component({
- selector: 'app-host',
- templateUrl: './host.component.html',
- styleUrls: ['./host.component.css'],
- // provide the service
- providers: [{ provide: FlowerService, useValue: { emoji: '🌷' } }]
+selector: 'app-host',
+templateUrl: './host.component.html',
+styleUrls: ['./host.component.css'],
+// provide the service
+providers: [{ provide: FlowerService, useValue: { emoji: '🌷' } }]
})
export class HostComponent {
- // use host when injecting the service
- flower = inject(FlowerService, {host: true, optional: true});
+// use host when injecting the service
+flower = inject(FlowerService, {host: true, optional: true});
}
-
+```
-Since `HostComponent` has the `host` option , no matter what the parent of `HostComponent` might have as a `flower.emoji` value, the `HostComponent` will use tulip 🌷.
+Since `HostComponent` has the `host` option , no matter what the parent of `HostComponent` might have as a `flower.emoji` value, the `HostComponent` will use tulip 🌷.
-### Modifiers with constructor injection
+### Modifiers with constructor injection
Similarly as presented before, the behavior of constructor injection can be modified with `@Optional()`, `@Self()`, `@SkipSelf()` and `@Host()`.
Import each of them from `@angular/core` and use each in the component class constructor when you inject your service.
-
+```ts {header:"src/app/self-no-data/self-no-data.component.ts" highlight:[3]}
export class SelfNoDataComponent {
constructor(@Self() @Optional() public leaf?: LeafService) { }
}
-
+```
## Logical structure of the template
@@ -329,11 +329,11 @@ Understanding the underlying logical structure of the Angular template will give
Components are used in your templates, as in the following example:
-
+```html
;
-
+```
HELPFUL: Usually, you declare the components and their templates in separate files.
For the purposes of understanding how the injection system works, it is useful to look at them from the point of view of a combined logical tree.
@@ -342,7 +342,7 @@ To mark the locations of where the component templates are located, this guide u
The following is an example of how the `` and `` view trees are combined into a single logical tree:
-
+```html
<#VIEW>
@@ -352,7 +352,7 @@ The following is an example of how the `` and `` view trees
#VIEW>
-
+```
Understanding the idea of the `<#VIEW>` demarcation is especially significant when you configure services in the component class.
@@ -363,8 +363,8 @@ The following sections demonstrate `providers` and `viewProviders` along with wa
A component class can provide services in two ways:
-| Arrays | Details |
-|:--- |:--- |
+| Arrays | Details |
+| :--------------------------- | :--------------------------------------------- |
| With a `providers` array | `@Component({ providers: [SomeService] })` |
| With a `viewProviders` array | `@Component({ viewProviders: [SomeService] })` |
@@ -375,40 +375,38 @@ For example, the logical tree will show that `` is a direct chi
In the logical tree, you will see special attributes: `@Provide`, `@Inject`, and `@ApplicationConfig`.
These aren't real attributes but are here to demonstrate what is going on under the hood.
-| Angular service attribute | Details |
-|:--- |:--- |
-| `@Inject(Token)=>Value` | If `Token` is injected at this location in the logical tree, its value would be `Value`. |
-| `@Provide(Token=Value)` | Indicates that `Token` is provided with `Value` at this location in the logical tree. |
-| `@ApplicationConfig` | Demonstrates that a fallback `EnvironmentInjector` should be used at this location. |
+| Angular service attribute | Details |
+| :------------------------ | :--------------------------------------------------------------------------------------- |
+| `@Inject(Token)=>Value` | If `Token` is injected at this location in the logical tree, its value would be `Value`. |
+| `@Provide(Token=Value)` | Indicates that `Token` is provided with `Value` at this location in the logical tree. |
+| `@ApplicationConfig` | Demonstrates that a fallback `EnvironmentInjector` should be used at this location. |
### Example app structure
-The example application has a `FlowerService` provided in `root` with an `emoji` value of red hibiscus 🌺.
+The example application has a `FlowerService` provided in `root` with an `emoji` value of red hibiscus 🌺.
-
+```ts {header:"src/app/flower.service.ts"}
@Injectable({
providedIn: 'root'
})
export class FlowerService {
emoji = '🌺';
}
-
+```
Consider an application with only an `AppComponent` and a `ChildComponent`.
The most basic rendered view would look like nested HTML elements such as the following:
-
-
+```html
-
-
+
+
-
-
+```
However, behind the scenes, Angular uses a logical view representation as follows when resolving injection requests:
-
+```html
<#VIEW>
@@ -417,7 +415,7 @@ However, behind the scenes, Angular uses a logical view representation as follow
#VIEW>
-
+```
The `<#VIEW>` here represents an instance of a template.
Notice that each component has its own `<#VIEW>`.
@@ -426,57 +424,55 @@ Knowledge of this structure can inform how you provide and inject your services,
Now, consider that `` injects the `FlowerService`:
-
+```typescript
export class AppComponent {
flower = inject(FlowerService);
}
-
+```
Add a binding to the `` template to visualize the result:
-
+```html
Emoji from FlowerService: {{flower.emoji}}
-
+```
The output in the view would be:
-
-Emoji from FlowerService: 🌺
-
+```shell
+Emoji from FlowerService: 🌺
+```
In the logical tree, this would be represented as follows:
-
+```html
"🌺">
+ @Inject(FlowerService) flower=>"🌺">
<#VIEW>
-
Emoji from FlowerService: {{flower.emoji}} (🌺)
+
Emoji from FlowerService: {{flower.emoji}} (🌺)
<#VIEW>
#VIEW>
#VIEW>
-
-
+```
When `` requests the `FlowerService`, it is the injector's job to resolve the `FlowerService` token.
The resolution of the token happens in two phases:
1. The injector determines the starting location in the logical tree and an ending location of the search.
- The injector begins with the starting location and looks for the token at each view level in the logical tree.
- If the token is found it is returned.
+ The injector begins with the starting location and looks for the token at each view level in the logical tree.
+ If the token is found it is returned.
1. If the token is not found, the injector looks for the closest parent `EnvironmentInjector` to delegate the request to.
In the example case, the constraints are:
1. Start with `<#VIEW>` belonging to `` and end with ``.
-
- * Normally the starting point for search is at the point of injection.
- However, in this case `` is a component. `@Component`s are special in that they also include their own `viewProviders`, which is why the search starts at `<#VIEW>` belonging to ``.
- This would not be the case for a directive matched at the same location.
- * The ending location happens to be the same as the component itself, because it is the topmost component in this application.
+ - Normally the starting point for search is at the point of injection.
+ However, in this case `` is a component. `@Component`s are special in that they also include their own `viewProviders`, which is why the search starts at `<#VIEW>` belonging to ``.
+ This would not be the case for a directive matched at the same location.
+ - The ending location happens to be the same as the component itself, because it is the topmost component in this application.
1. The `EnvironmentInjector` provided by the `ApplicationConfig` acts as the fallback injector when the injection token can't be found in the `ElementInjector` hierarchies.
@@ -484,61 +480,59 @@ In the example case, the constraints are:
Now, in the `ChildComponent` class, add a provider for `FlowerService` to demonstrate more complex resolution rules in the upcoming sections:
-
+```typescript
@Component({
- selector: 'app-child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.css'],
- // use the providers array to provide a service
- providers: [{ provide: FlowerService, useValue: { emoji: '🌻' } }]
+selector: 'app-child',
+templateUrl: './child.component.html',
+styleUrls: ['./child.component.css'],
+// use the providers array to provide a service
+providers: [{ provide: FlowerService, useValue: { emoji: '🌻' } }]
})
export class ChildComponent {
- // inject the service
- flower = inject(FlowerService);
+// inject the service
+flower = inject(FlowerService);
}
-
+```
Now that the `FlowerService` is provided in the `@Component()` decorator, when the `` requests the service, the injector has only to look as far as the `ElementInjector` in the ``.
It won't have to continue the search any further through the injector tree.
The next step is to add a binding to the `ChildComponent` template.
-
+```html
Emoji from FlowerService: {{flower.emoji}}
-
+```
To render the new values, add `` to the bottom of the `AppComponent` template so the view also displays the sunflower:
-
+```shell
Child Component
-Emoji from FlowerService: 🌻
-
+Emoji from FlowerService: 🌻
+```
In the logical tree, this is represented as follows:
-
-
+```html
"🌺">
- <#VIEW>
-
+#VIEW>
+
+#VIEW>
-
-
+```
When `` requests the `FlowerService`, the injector begins its search at the `<#VIEW>` belonging to `` \(`<#VIEW>` is included because it is injected from `@Component()`\) and ends with ``.
-In this case, the `FlowerService` is resolved in the `providers` array with sunflower 🌻 of the ``.
+In this case, the `FlowerService` is resolved in the `providers` array with sunflower 🌻 of the ``.
The injector doesn't have to look any further in the injector tree.
-It stops as soon as it finds the `FlowerService` and never sees the red hibiscus 🌺.
+It stops as soon as it finds the `FlowerService` and never sees the red hibiscus 🌺.
### Using the `viewProviders` array
@@ -551,97 +545,93 @@ For step-by-step instructions, continue with this section.
If you can set it up on your own, skip ahead to [Modifying service availability](#visibility-of-provided-tokens).
For demonstration, we are building an `AnimalService` to demonstrate `viewProviders`.
-First, create an `AnimalService` with an `emoji` property of whale 🐳:
+First, create an `AnimalService` with an `emoji` property of whale 🐳:
-
+```typescript
import { Injectable } from '@angular/core';
@Injectable({
- providedIn: 'root'
+providedIn: 'root'
})
export class AnimalService {
- emoji = '🐳';
+emoji = '🐳';
}
-
+```
Following the same pattern as with the `FlowerService`, inject the `AnimalService` in the `AppComponent` class:
-
+```typescript
export class AppComponent {
public flower = inject(FlowerService);
public animal = inject(AnimalService);
}
-
+```
HELPFUL: You can leave all the `FlowerService` related code in place as it will allow a comparison with the `AnimalService`.
Add a `viewProviders` array and inject the `AnimalService` in the `` class, too, but give `emoji` a different value.
-Here, it has a value of dog 🐶.
+Here, it has a value of dog 🐶.
-
+```typescript
@Component({
- selector: 'app-child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.css'],
- // provide services
- providers: [{ provide: FlowerService, useValue: { emoji: '🌻' } }],
- viewProviders: [{ provide: AnimalService, useValue: { emoji: '🐶' } }]
+selector: 'app-child',
+templateUrl: './child.component.html',
+styleUrls: ['./child.component.css'],
+// provide services
+providers: [{ provide: FlowerService, useValue: { emoji: '🌻' } }],
+viewProviders: [{ provide: AnimalService, useValue: { emoji: '🐶' } }]
})
export class ChildComponent {
- // inject services
- flower = inject(FlowerService);
- animal = inject(AnimalService)
+// inject services
+flower = inject(FlowerService);
+animal = inject(AnimalService)
...
}
-
+```
Add bindings to the `ChildComponent` and the `AppComponent` templates.
In the `ChildComponent` template, add the following binding:
-
+```html
Emoji from AnimalService: {{animal.emoji}}
-
+```
Additionally, add the same to the `AppComponent` template:
-
+```html
Emoji from AnimalService: {{animal.emoji}}
s
-
+```
Now you should see both values in the browser:
-
-
+```shell
AppComponent
-Emoji from AnimalService: 🐳
+Emoji from AnimalService: 🐳
Child Component
-Emoji from AnimalService: 🐶
-
-
+Emoji from AnimalService: 🐶
+```
The logic tree for this example of `viewProviders` is as follows:
-
-
+```html
"🐳">
- <#VIEW>
-
- <#VIEW @Provide(AnimalService="🐶")
- @Inject(AnimalService=>"🐶")>
-
-
+#VIEW>
+
+#VIEW>
+
+```
Just as with the `FlowerService` example, the `AnimalService` is provided in the `` `@Component()` decorator.
-This means that since the injector first looks in the `ElementInjector` of the component, it finds the `AnimalService` value of dog 🐶.
+This means that since the injector first looks in the `ElementInjector` of the component, it finds the `AnimalService` value of dog 🐶.
It doesn't need to continue searching the `ElementInjector` tree, nor does it need to search the `ModuleInjector`.
### `providers` vs. `viewProviders`
@@ -653,36 +643,33 @@ To see the difference between using `providers` and `viewProviders`, add another
`InspectorComponent` will be a child of the `ChildComponent`.
In `inspector.component.ts`, inject the `FlowerService` and `AnimalService` during property initialization:
-
+```typescript
export class InspectorComponent {
flower = inject(FlowerService);
animal = inject(AnimalService);
}
-
+```
You do not need a `providers` or `viewProviders` array.
Next, in `inspector.component.html`, add the same markup from previous components:
-
+```html
Emoji from FlowerService: {{flower.emoji}}
Emoji from AnimalService: {{animal.emoji}}
-
+```
Remember to add the `InspectorComponent` to the `ChildComponent` `imports` array.
-
+```typescript
@Component({
- ...
- imports: [InspectorComponent]
+...
+imports: [InspectorComponent]
})
-
-
+```
Next, add the following to `child.component.html`:
-
+```html
...
@@ -692,72 +679,71 @@ Next, add the following to `child.component.html`:
Inside the view
-
+```
`` allows you to project content, and `` inside the `ChildComponent` template makes the `InspectorComponent` a child component of `ChildComponent`.
Next, add the following to `app.component.html` to take advantage of content projection.
-
+```html
-
+```
The browser now renders the following, omitting the previous examples for brevity:
-
+```shell
...
Content projection
-Emoji from FlowerService: 🌻
-Emoji from AnimalService: 🐳
-
-Emoji from FlowerService: 🌻
-Emoji from AnimalService: 🐶
+Emoji from FlowerService: 🌻
+Emoji from AnimalService: 🐳
-
+Emoji from FlowerService: 🌻
+Emoji from AnimalService: 🐶
+```
These four bindings demonstrate the difference between `providers` and `viewProviders`.
-Remember that the dog emoji 🐶 is declared inside the `<#VIEW>` of `ChildComponent` and isn't visible to the projected content.
-Instead, the projected content sees the whale 🐳.
+Remember that the dog emoji 🐶 is declared inside the `<#VIEW>` of `ChildComponent` and isn't visible to the projected content.
+Instead, the projected content sees the whale 🐳.
-However, in the next output section though, the `InspectorComponent` is an actual child component of `ChildComponent`, `InspectorComponent` is inside the `<#VIEW>`, so when it asks for the `AnimalService`, it sees the dog 🐶.
+However, in the next output section though, the `InspectorComponent` is an actual child component of `ChildComponent`, `InspectorComponent` is inside the `<#VIEW>`, so when it asks for the `AnimalService`, it sees the dog 🐶.
The `AnimalService` in the logical tree would look like this:
-
-
+```html
"🐳">
- <#VIEW>
-
- <#VIEW @Provide(AnimalService="🐶")
- @Inject(AnimalService=>"🐶")>
-
-
#VIEW>
#VIEW>
- #VIEW>
-
-
+#VIEW>
+
+```
-The projected content of `` sees the whale 🐳, not the dog 🐶, because the dog 🐶 is inside the `` `<#VIEW>`.
-The `` can only see the dog 🐶 if it is also within the `<#VIEW>`.
+The projected content of `` sees the whale 🐳, not the dog 🐶, because the dog 🐶 is inside the `` `<#VIEW>`.
+The `` can only see the dog 🐶 if it is also within the `<#VIEW>`.
### Visibility of provided tokens
@@ -767,157 +753,149 @@ To do this, place visibility configuration at the point of injection, that is, w
To alter where the injector starts looking for `FlowerService`, add `skipSelf` to the `` `inject()` invocation where `FlowerService` is injected.
This invocation is a property initializer the `` as shown in `child.component.ts`:
-
+```typescript
flower = inject(FlowerService, { skipSelf: true })
-
+```
With `skipSelf`, the `` injector doesn't look to itself for the `FlowerService`.
Instead, the injector starts looking for the `FlowerService` at the `ElementInjector` of the ``, where it finds nothing.
-Then, it goes back to the `` `ModuleInjector` and finds the red hibiscus 🌺 value, which is available because `` and `` share the same `ModuleInjector`.
+Then, it goes back to the `` `ModuleInjector` and finds the red hibiscus 🌺 value, which is available because `` and `` share the same `ModuleInjector`.
The UI renders the following:
-
-
-Emoji from FlowerService: 🌺
-
-
+```shell
+Emoji from FlowerService: 🌺
+```
In a logical tree, this same idea might look like this:
-
-
+```html
"🌺">
- <#VIEW>
-
- <#VIEW @Inject(FlowerService, SkipSelf)=>"🌺">
-
- #VIEW>
-
- #VIEW>
-
+@Inject(FlowerService) flower=>"🌺">
+<#VIEW>
+
+<#VIEW @Inject(FlowerService, SkipSelf)=>"🌺">
-
+
-Though `` provides the sunflower 🌻, the application renders the red hibiscus 🌺 because `skipSelf` causes the current injector (`app-child`) to skip itself and look to its parent.
+#VIEW>
+
+#VIEW>
+
+```
+
+Though `` provides the sunflower 🌻, the application renders the red hibiscus 🌺 because `skipSelf` causes the current injector (`app-child`) to skip itself and look to its parent.
If you now add `host` (in addition to the `skipSelf`), the result will be `null`.
This is because `host` limits the upper bound of the search to the `app-child` `<#VIEW>`.
Here's the idea in the logical tree:
-
-
+```html
"🌺">
- <#VIEW>
-
- <#VIEW inject(FlowerService, {skipSelf: true, host: true, optional:true})=>null>
- #VIEW>
-
- #VIEW>
+@Inject(FlowerService) flower=>"🌺">
+<#VIEW>
+
+<#VIEW inject(FlowerService, {skipSelf: true, host: true, optional:true})=>null>
+#VIEW>
+
+#VIEW>
-
-
+```
Here, the services and their values are the same, but `host` stops the injector from looking any further than the `<#VIEW>` for `FlowerService`, so it doesn't find it and returns `null`.
### `skipSelf` and `viewProviders`
-Remember, `` provides the `AnimalService` in the `viewProviders` array with the value of dog 🐶.
-Because the injector has only to look at the `ElementInjector` of the `` for the `AnimalService`, it never sees the whale 🐳.
+Remember, `` provides the `AnimalService` in the `viewProviders` array with the value of dog 🐶.
+Because the injector has only to look at the `ElementInjector` of the `` for the `AnimalService`, it never sees the whale 🐳.
-As in the `FlowerService` example, if you add `skipSelf` to the `inject()` of `AnimalService`, the injector won't look in the `ElementInjector` of the current `` for the `AnimalService`.
+As in the `FlowerService` example, if you add `skipSelf` to the `inject()` of `AnimalService`, the injector won't look in the `ElementInjector` of the current `` for the `AnimalService`.
Instead, the injector will begin at the `` `ElementInjector`.
-
+```typescript
@Component({
selector: 'app-child',
…
viewProviders: [
- { provide: AnimalService, useValue: { emoji: '🐶' } },
+ { provide: AnimalService, useValue: { emoji: '🐶' } },
],
})
-
+```
The logical tree looks like this with `skipSelf` in ``:
-
-
+```html
"🐳")>
- <#VIEW>
-
- <#VIEW @Provide(AnimalService="🐶")
- @Inject(AnimalService, SkipSelf=>"🐳")>
-
- #VIEW>
-
- #VIEW>
-
+@Inject(AnimalService=>"🐳")>
+<#VIEW>
+
+<#VIEW @Provide(AnimalService="🐶")
+@Inject(AnimalService, SkipSelf=>"🐳")>
-
+
+
+#VIEW>
+
+#VIEW>
+
+```
-With `skipSelf` in the ``, the injector begins its search for the `AnimalService` in the `` `ElementInjector` and finds whale 🐳.
+With `skipSelf` in the ``, the injector begins its search for the `AnimalService` in the `` `ElementInjector` and finds whale 🐳.
### `host` and `viewProviders`
-If you just use `host` for the injection of `AnimalService`, the result is dog 🐶 because the injector finds the `AnimalService` in the `` `<#VIEW>` itself.
+If you just use `host` for the injection of `AnimalService`, the result is dog 🐶 because the injector finds the `AnimalService` in the `` `<#VIEW>` itself.
The `ChildComponent` configures the `viewProviders` so that the dog emoji is provided as `AnimalService` value.
You can also see `host` the `inject()`:
-
+```typescript
@Component({
selector: 'app-child',
…
viewProviders: [
- { provide: AnimalService, useValue: { emoji: '🐶' } },
+ { provide: AnimalService, useValue: { emoji: '🐶' } },
]
})
export class ChildComponent {
animal = inject(AnimalService, { host: true })
}
-
+```
`host: true` causes the injector to look until it encounters the edge of the `<#VIEW>`.
-
-
+```html
"🐳")>
- <#VIEW>
-
- <#VIEW @Provide(AnimalService="🐶")
- inject(AnimalService, {host: true}=>"🐶")>
- #VIEW>
-
- #VIEW>
+@Inject(AnimalService=>"🐳")>
+<#VIEW>
+
+<#VIEW @Provide(AnimalService="🐶")
+inject(AnimalService, {host: true}=>"🐶")>
+#VIEW>
+
+#VIEW>
+```
-
-
-Add a `viewProviders` array with a third animal, hedgehog 🦔, to the `app.component.ts` `@Component()` metadata:
+Add a `viewProviders` array with a third animal, hedgehog 🦔, to the `app.component.ts` `@Component()` metadata:
-
+```typescript
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
viewProviders: [
- { provide: AnimalService, useValue: { emoji: '🦔' } },
+ { provide: AnimalService, useValue: { emoji: '🦔' } },
],
})
-
-
+```
Next, add `skipSelf` along with `host` to the `inject()` for the `AnimalService` injection in `child.component.ts`.
Here are `host` and `skipSelf` in the `animal` property initialization:
-
+```typescript
export class ChildComponent {
animal = inject(AnimalService, { host: true, skipSelf: true });
}
-
-
+```
-
- <#VIEW @Provide(AnimalService="🐶")
- inject(AnimalService, {skipSelf:true, host: true, optional: true})=>"🦔">
-
- #VIEW>
-
- #VIEW>
-
+@Inject(AnimalService=>"🐳")>
+<#VIEW @Provide(AnimalService="🦔")
+@Inject(AnimalService, @Optional)=>"🦔">
-
+
+
+<#VIEW @Provide(AnimalService="🐶")
+inject(AnimalService, {skipSelf:true, host: true, optional: true})=>"🦔">
+
+#VIEW>
+
+#VIEW>
+
+```
`skipSelf`, causes the injector to start its search for the `AnimalService` at the ``, not the ``, where the request originates, and `host` stops the search at the `` `<#VIEW>`.
-Since `AnimalService` is provided by way of the `viewProviders` array, the injector finds hedgehog 🦔 in the `<#VIEW>`.
+Since `AnimalService` is provided by way of the `viewProviders` array, the injector finds hedgehog 🦔 in the `<#VIEW>`.
## Example: `ElementInjector` use cases
@@ -966,15 +943,14 @@ If you later modify the `VillainsService`, you could break something in other co
Instead, you should provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:
-
+```typescript
@Component({
- selector: 'app-villains-list',
- templateUrl: './villains-list.component.html',
- providers: [VillainsService]
+selector: 'app-villains-list',
+templateUrl: './villains-list.component.html',
+providers: [VillainsService]
})
export class VillainsListComponent {}
-
+```
By providing `VillainsService` in the `VillainsListComponent` metadata and nowhere else, the service becomes available only in the `VillainsListComponent` and its subcomponent tree.
@@ -993,9 +969,9 @@ Each selected hero tax return opens in its own component and multiple returns ca
Each tax return component has the following characteristics:
-* Is its own tax return editing session
-* Can change a tax return without affecting a return in another component
-* Has the ability to save the changes to its tax return or cancel them
+- Is its own tax return editing session
+- Can change a tax return without affecting a return in another component
+- Has the ability to save the changes to its tax return or cancel them
Suppose that the `HeroTaxReturnComponent` had logic to manage and restore changes.
That would be a straightforward task for a hero tax return.
@@ -1005,88 +981,88 @@ You could delegate that management to a helper service, as this example does.
The `HeroTaxReturnService` caches a single `HeroTaxReturn`, tracks changes to that return, and can save or restore it.
It also delegates to the application-wide singleton `HeroService`, which it gets by injection.
-
+```typescript
import { Injectable } from '@angular/core';
import { HeroTaxReturn } from './hero';
import { HeroesService } from './heroes.service';
@Injectable()
export class HeroTaxReturnService {
- private currentTaxReturn!: HeroTaxReturn;
- private originalTaxReturn!: HeroTaxReturn;
+private currentTaxReturn!: HeroTaxReturn;
+private originalTaxReturn!: HeroTaxReturn;
- private heroService = inject(HeroesService);
+private heroService = inject(HeroesService);
- set taxReturn(htr: HeroTaxReturn) {
- this.originalTaxReturn = htr;
- this.currentTaxReturn = htr.clone();
- }
+set taxReturn(htr: HeroTaxReturn) {
+this.originalTaxReturn = htr;
+this.currentTaxReturn = htr.clone();
+}
- get taxReturn(): HeroTaxReturn {
- return this.currentTaxReturn;
- }
+get taxReturn(): HeroTaxReturn {
+return this.currentTaxReturn;
+}
- restoreTaxReturn() {
- this.taxReturn = this.originalTaxReturn;
- }
+restoreTaxReturn() {
+this.taxReturn = this.originalTaxReturn;
+}
- saveTaxReturn() {
- this.taxReturn = this.currentTaxReturn;
- this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe();
- }
+saveTaxReturn() {
+this.taxReturn = this.currentTaxReturn;
+this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe();
+}
}
-
+```
Here is the `HeroTaxReturnComponent` that makes use of `HeroTaxReturnService`.
-
+```typescript
import { Component, EventEmitter, input, output } from '@angular/core';
import { HeroTaxReturn } from './hero';
import { HeroTaxReturnService } from './hero-tax-return.service';
@Component({
- selector: 'app-hero-tax-return',
- templateUrl: './hero-tax-return.component.html',
- styleUrls: [ './hero-tax-return.component.css' ],
- providers: [ HeroTaxReturnService ]
+selector: 'app-hero-tax-return',
+templateUrl: './hero-tax-return.component.html',
+styleUrls: [ './hero-tax-return.component.css' ],
+providers: [ HeroTaxReturnService ]
})
export class HeroTaxReturnComponent {
- message = '';
+message = '';
- close = output();
+close = output();
- get taxReturn(): HeroTaxReturn {
- return this.heroTaxReturnService.taxReturn;
- }
+get taxReturn(): HeroTaxReturn {
+return this.heroTaxReturnService.taxReturn;
+}
- taxReturn = input.required();
+taxReturn = input.required();
- constructor() {
- effect(() => {
- this.heroTaxReturnService.taxReturn = this.taxReturn();
- })
- }
+constructor() {
+effect(() => {
+this.heroTaxReturnService.taxReturn = this.taxReturn();
+})
+}
- private heroTaxReturnService = inject(HeroTaxReturnService);
+private heroTaxReturnService = inject(HeroTaxReturnService);
- onCanceled() {
- this.flashMessage('Canceled');
- this.heroTaxReturnService.restoreTaxReturn();
- }
+onCanceled() {
+this.flashMessage('Canceled');
+this.heroTaxReturnService.restoreTaxReturn();
+}
- onClose() { this.close.emit(); }
+onClose() { this.close.emit(); }
- onSaved() {
- this.flashMessage('Saved');
- this.heroTaxReturnService.saveTaxReturn();
- }
+onSaved() {
+this.flashMessage('Saved');
+this.heroTaxReturnService.saveTaxReturn();
+}
- flashMessage(msg: string) {
- this.message = msg;
- setTimeout(() => this.message = '', 500);
- }
+flashMessage(msg: string) {
+this.message = msg;
+setTimeout(() => this.message = '', 500);
+}
}
-
+```
The _tax-return-to-edit_ arrives by way of the `input` property, which is implemented with getters and setters.
The setter initializes the component's own instance of the `HeroTaxReturnService` with the incoming return.
@@ -1098,9 +1074,9 @@ Every component would share the same service instance, and each component would
To prevent this, configure the component-level injector of `HeroTaxReturnComponent` to provide the service, using the `providers` property in the component metadata.
-
+```typescript
providers: [HeroTaxReturnService]
-
+```
The `HeroTaxReturnComponent` has its own provider of the `HeroTaxReturnService`.
Recall that every component _instance_ has its own injector.
@@ -1116,7 +1092,7 @@ For example, consider a `Car` component that includes tire service information a
The root injector, marked as (A), uses _generic_ providers for details about `CarService` and `EngineService`.
-1. `Car` component (A). Component (A) displays tire service data about a car and specifies generic services to provide more information about the car.
+1. `Car` component (A). Component (A) displays tire service data about a car and specifies generic services to provide more information about the car.
2. Child component (B). Component (B) defines its own, _specialized_ providers for `CarService` and `EngineService` that have special capabilities suitable for what's going on in component (B).
@@ -1141,9 +1117,9 @@ Behind the scenes, each component sets up its own injector with zero, one, or mo
When you resolve an instance of `Car` at the deepest component (C), its injector produces:
-* An instance of `Car` resolved by injector (C)
-* An `Engine` resolved by injector (B)
-* Its `Tires` resolved by the root injector (A).
+- An instance of `Car` resolved by injector (C)
+- An `Engine` resolved by injector (B)
+- Its `Tires` resolved by the root injector (A).
```mermaid
graph BT;
diff --git a/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md b/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md
index 836b1aed52..33eaa8672e 100644
--- a/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md
+++ b/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md
@@ -1,23 +1,17 @@
-## 階層型インジェクター
+# 階層型インジェクター
-Angularのインジェクターには、注入可能なオブジェクトのアプリケーション内での可視性を思いどおりにするために活用できるルールがあります。
-これらのルールを理解することで、プロバイダーをアプリケーションレベル、コンポーネント内、またはディレクティブ内で宣言する必要があるかどうかを判断できます。
+このガイドでは、解決ルール、修飾子、および高度なパターンを含む、Angularの階層的な依存性の注入システムについて詳しく説明します。
-Angularで構築するアプリケーションは非常に大きくなる可能性があり、この複雑さを管理する1つの方法は、アプリケーションを明確に定義されたコンポーネントツリーに分割することです。
+NOTE: インジェクター階層とプロバイダースコープに関する基本概念については、[依存性プロバイダーの定義ガイド](guide/di/defining-dependency-providers#injector-hierarchy-in-angular)を参照してください。
-ページのセクションには、アプリケーションの残りの部分とは完全に独立して動作する部分があり、そのセクションに必要なサービスやその他の依存関係のローカルコピーが持つことができます。
-これらのアプリケーションセクションが使用するサービスの一部は、アプリケーションの他の部分やコンポーネントツリーの上位にある親コンポーネントと共有される場合がありますが、他の依存関係はプライベートであることを目的としています。
-
-階層型の依存性の注入を使用すると、アプリケーションのセクションを分離してアプリケーションの残りの部分と共有されていない独自のプライベート依存関係を与えるか、親コンポーネントが特定の依存関係を子コンポーネントのみに共有してコンポーネントツリーの残りの部分には共有しないようにできます。階層型の依存性の注入により、必要な場合にのみ、アプリケーションのさまざまな部分間で依存関係を共有できます。
-
-## インジェクター階層のタイプ
+## インジェクター階層のタイプ {#types-of-injector-hierarchies}
Angularには、次の2つのインジェクター階層があります。
-| インジェクター階層 | 詳細 |
-|:--- |:--- |
-| `EnvironmentInjector` 階層 | `@Injectable()` または `ApplicationConfig` の `providers` 配列を使用して、この階層で `EnvironmentInjector` を構成します。 |
-| `ElementInjector` 階層 | 各 DOM 要素で暗黙的に作成されます。 `ElementInjector` は、 `@Directive()` または `@Component()` の `providers` プロパティで構成しない限り、デフォルトでは空です。 |
+| インジェクター階層 | 詳細 |
+| :--------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `EnvironmentInjector` 階層 | `@Injectable()` または `ApplicationConfig` の `providers` 配列を使用して、この階層で `EnvironmentInjector` を構成します。 |
+| `ElementInjector` 階層 | 各 DOM 要素で暗黙的に作成されます。 `ElementInjector` は、 `@Directive()` または `@Component()` の `providers` プロパティで構成しない限り、デフォルトでは空です。 |
`NgModule` ベースのアプリケーションの場合、`@NgModule()` または `@Injectable()` アノテーションを使用して、`ModuleInjector` 階層で依存関係を提供できます。
@@ -27,8 +21,8 @@ Angularには、次の2つのインジェクター階層があります。
`EnvironmentInjector` は、次のいずれかの方法で構成できます。
-* `@Injectable()` の `providedIn` プロパティを使用して `root` または `platform` を参照する
-* `ApplicationConfig` の `providers` 配列を使用する
+- `@Injectable()` の `providedIn` プロパティを使用して `root` または `platform` を参照する
+- `ApplicationConfig` の `providers` 配列を使用する
@@ -42,17 +36,16 @@ Angularには、次の2つのインジェクター階層があります。
`providedIn` を使用して、次のように `@Injectable()` を使用してサービスを提供します。
-
+```ts {highlight:[4]}
import { Injectable } from '@angular/core';
@Injectable({
- providedIn: 'root' // <--ルート EnvironmentInjector でこのサービスを提供します
+ providedIn: 'root' // <--ルート EnvironmentInjector でこのサービスを提供します
})
export class ItemService {
name = 'telephone';
}
-
-
+```
`@Injectable()` デコレーターは、サービスクラスを識別します。
`providedIn` プロパティは、特定の `EnvironmentInjector`(ここでは `root`)を構成します。これにより、サービスは `root` `EnvironmentInjector` で使用可能になります。
@@ -61,22 +54,22 @@ export class ItemService {
`NgModule` ベースのアプリケーションの場合、`ModuleInjector` は、次のいずれかの方法で構成できます。
-* `@Injectable()` の `providedIn` プロパティを使用して `root` または `platform` を参照する
-* `@NgModule()` の `providers` 配列を使用する
+- `@Injectable()` の `providedIn` プロパティを使用して `root` または `platform` を参照する
+- `@NgModule()` の `providers` 配列を使用する
`ModuleInjector` は、 `@NgModule.providers` および `NgModule.imports` プロパティによって構成されます。 `ModuleInjector` は、 `NgModule.imports` を再帰的にたどることによって到達できるすべてのプロバイダー配列をフラット化したものです。
子 `ModuleInjector` 階層は、他の `@NgModules` を遅延読み込みするときに作成されます。
-### プラットフォームインジェクター
+### プラットフォームインジェクター {#platform-injector}
`root` の上にさらに2つのインジェクター、追加の `EnvironmentInjector` と `NullInjector()` があります。
Angularが `main.ts` の次の内容でアプリケーションをブートストラップする方法を検討してください。
-
+```ts
bootstrapApplication(AppComponent, appConfig);
-
+```
`bootstrapApplication()` メソッドは、 `ApplicationConfig` インスタンスによって構成されたプラットフォームインジェクターの子インジェクターを作成します。
これが `root` `EnvironmentInjector` です。
@@ -111,7 +104,7 @@ stateDiagram-v2
`bootstrapApplication()` の `ApplicationConfig` でアプリケーション全体のプロバイダーを構成すると、 `@Injectable()` メタデータの `root` で構成されたプロバイダーがオーバーライドされます。
-これは、複数のアプリケーションで共有されるサービスのデフォルト以外を構成する場合に行うことができます。
+これは、複数のアプリケーションで共有されるサービスのデフォルト以外のプロバイダーを構成する場合に行うことができます。
コンポーネントルーターの構成にデフォルト以外の [ロケーション戦略](guide/routing#location-strategy) が含まれている場合、 `ApplicationConfig` の `providers` リストにそのプロバイダーをリストすることによって、その例を示します。
@@ -132,13 +125,13 @@ Angularは、各DOM要素に対して `ElementInjector` 階層を暗黙的に作
`@Component()` デコレーターの `providers` または `viewProviders` プロパティを使用してサービスを提供すると、 `ElementInjector` が構成されます。
たとえば、次の `TestComponent` は、次のようにサービスを提供することで `ElementInjector` を構成します。
-
+```ts {highlight:[3]}
@Component({
- …
+ /* … */
providers: [{ provide: ItemService, useValue: { name: 'lamp' } }]
})
export class TestComponent
-
+```
HELPFUL: [解決ルール](#resolution-rules) セクションを参照して、 `EnvironmentInjector` ツリー、 `ModuleInjector`、および `ElementInjector` ツリーの関係を理解してください。
@@ -175,50 +168,49 @@ Angularは同じサービスの別のプロバイダーを探しません。
HELPFUL: `NgModule` ベースのアプリケーションの場合、Angularは `ElementInjector` 階層でプロバイダーが見つからない場合、 `ModuleInjector` 階層を検索します。
-## 解決修飾子
+## 解決修飾子 {#resolution-modifiers}
-Angular's resolution behavior can be modified with `optional`, `self`, `skipSelf` and `host`.
-Import each of them from `@angular/core` and use each in the `inject` configuration when you inject your service.
+Angularの解決動作は、`optional`、`self`、`skipSelf`、および `host` を使用して変更できます。
+`@angular/core` からそれぞれをインポートし、サービスを注入するときに `inject` 構成でそれぞれを使用します。
-### 修飾子の種類
+### 修飾子の種類 {#types-of-modifiers}
解決修飾子は、次の3つのカテゴリーに分類されます。
-* What to do if Angular doesn't find what you're looking for, that is `optional`
-* Where to start looking, that is `skipSelf`
-* Where to stop looking, `host` and `self`
+- Angularが探しているものを見つけられない場合にどうするか、つまり `optional`
+- どこから探し始めるか、つまり `skipSelf`
+- どこで探すのをやめるか、`host` および `self`
デフォルトでは、Angularは常に現在の `Injector` から始めて、すべてを上に検索し続けます。
修飾子を使用すると、開始位置(または _self_ 位置)と終了位置を変更できます。
-さらに、次の修飾子をすべて組み合わせることができます。
+さらに、次の修飾子を除いて、すべての修飾子を組み合わせることができます。
-* `host` and `self`
-* `skipSelf` and `self`.
+- `host` と `self`
+- `skipSelf` と `self`
### `optional`
-`optional` allows Angular to consider a service you inject to be optional.
+`optional` を使用すると、Angularは注入するサービスをオプションと見なすことができます。
そのため、実行時に解決できない場合、Angularはサービスをエラーをスローするのではなく、 `null` として解決します。
次の例では、サービス `OptionalService` はサービス `ApplicationConfig`や`@NgModule()`、コンポーネントクラスで提供されていないため、アプリケーションのどこにも使用できません。
-
+```ts {header:"src/app/optional/optional.component.ts"}
export class OptionalComponent {
public optional? = inject(OptionalService, {optional: true});
}
-
+```
### `self`
-Use `self` so that Angular will only look at the `ElementInjector` for the current component or directive.
+`self` を使用すると、Angularは現在のコンポーネントまたはディレクティブの `ElementInjector` のみを調べます。
-A good use case for `self` is to inject a service but only if it is available on the current host element.
-To avoid errors in this situation, combine `self` with `optional`.
+`self` の適切なユースケースは、サービスを注入するが、現在のホスト要素で使用可能な場合のみにすることです。
+このような状況でエラーを回避するには、`self` を `optional` と組み合わせます。
-For example, in the following `SelfNoDataComponent`, notice the injected `LeafService` as a property.
+たとえば、次の `SelfNoDataComponent` では、プロパティとして注入された `LeafService` に注目してください。
-
+```ts {header:"src/app/self-no-data/self-no-data.component.ts", highlight=[7]}>
@Component({
selector: 'app-self-no-data',
templateUrl: './self-no-data.component.html',
@@ -227,101 +219,109 @@ For example, in the following `SelfNoDataComponent`, notice the injected `LeafSe
export class SelfNoDataComponent {
public leaf = inject(LeafService, {optional: true, self: true});
}
-
+```
-In this example, there is a parent provider and injecting the service will return the value, however, injecting the service with `self` and `optional` will return `null` because `self` tells the injector to stop searching in the current host element.
+この例では、親プロバイダーがあり、サービスを注入すると値が返されますが、`self` と `optional` を使用してサービスを注入すると `null` が返されます。これは、`self` がインジェクターに現在のホスト要素で検索を停止するよう指示するためです。
別の例では、 `FlowerService` のプロバイダーを備えたコンポーネントクラスを示しています。
-この場合、インジェクターは現在の `ElementInjector` より先を見ずに、 `FlowerService` を見つけて、チューリップ 🌷 を返します。
+この場合、インジェクターは現在の `ElementInjector` より先を見ずに、 `FlowerService` を見つけて、チューリップ 🌷 を返します。
-
+```ts {header:"src/app/self/self.component.ts"}
+@Component({
+ selector: 'app-self',
+ templateUrl: './self.component.html',
+ styleUrls: ['./self.component.css'],
+ providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}],
+})
+export class SelfComponent {
+ constructor(@Self() public flower: FlowerService) {}
+}
+```
### `skipSelf`
-`skipSelf` is the opposite of `self`.
-With `skipSelf`, Angular starts its search for a service in the parent `ElementInjector`, rather than in the current one.
-そのため、親 `ElementInjector` が `emoji` にシダ 🌿 値を使用していたが、コンポーネントの `providers` 配列にカエデの葉 🍁 が含まれている場合、Angular はカエデの葉 🍁 を無視して、シダ 🌿 を使用します。
+`skipSelf` は `self` の反対です。
+`skipSelf` を使用すると、Angularは現在の `ElementInjector` ではなく、親 `ElementInjector` でサービスの検索を開始します。
+そのため、親`ElementInjector`が`emoji`にシダ🌿値を使用していたが、コンポーネントの`providers`配列にカエデの葉🍁が含まれている場合、Angularはカエデの葉🍁を無視して、シダ🌿を使用します。
これをコードで確認するために、親コンポーネントが使用する `emoji` の次の値を想定します。これは、このサービスと同じです。
-
+```ts {header:"src/app/leaf.service.ts"}
export class LeafService {
- emoji = '🌿';
+ emoji = '🌿';
}
-
+```
-子コンポーネントに、異なる値、カエデの葉 🍁 が含まれていると想像してください。ただし、親の値を使用したいとします。
-This is when you'd use `skipSelf`:
+子コンポーネントに、異なる値、カエデの葉 🍁 が含まれていると想像してください。ただし、親の値を使用したいとします。
+これが `skipSelf` を使用する場合です。
-
+```ts {header:"src/app/skipself/skipself.component.ts" highlight:[[6],[10]]}
@Component({
selector: 'app-skipself',
templateUrl: './skipself.component.html',
styleUrls: ['./skipself.component.css'],
// Angular はこの LeafService インスタンスを無視します
- providers: [{ provide: LeafService, useValue: { emoji: '🍁' } }]
+ providers: [{ provide: LeafService, useValue: { emoji: '🍁' } }]
})
export class SkipselfComponent {
// Use skipSelf as inject option
public leaf = inject(LeafService, {skipSelf: true});
}
-
+```
-この場合、 `emoji` に対して取得する値は、カエデの葉 🍁 ではなく、シダ 🌿 になります。
+この場合、 `emoji` に対して取得する値は、カエデの葉 🍁 ではなく、シダ 🌿 になります。
-#### `skipSelf` option with `optional`
+#### `skipSelf` オプションと `optional` {#skipself-option-with-optional}
-Use the `skipSelf` option with `optional` to prevent an error if the value is `null`.
+値が `null` の場合にエラーを防ぐために、`skipSelf` オプションを `optional` と一緒に使用します。
-In the following example, the `Person` service is injected during property initialization.
-`skipSelf` tells Angular to skip the current injector and `optional` will prevent an error should the `Person` service be `null`.
+次の例では、 `Person` サービスはプロパティの初期化中に注入されます。
+`skipSelf` はAngularに現在のインジェクターをスキップするよう指示し、`optional` は `Person` サービスが `null` の場合にエラーを防ぎます。
-
+```ts
class Person {
parent = inject(Person, {optional: true, skipSelf: true})
}
-
+```
### `host`
-`host` lets you designate a component as the last stop in the injector tree when searching for providers.
+`host` を使用すると、プロバイダーを検索するときに、コンポーネントをインジェクターツリーの最後の停止点として指定できます。
-Even if there is a service instance further up the tree, Angular won't continue looking.
-Use `host` as follows:
+ツリーのさらに上にサービスインスタンスがある場合でも、Angularは検索を続けません。
+`host` を次のように使用します。
-
+```ts {header:"src/app/host/host.component.ts" highlight:[[6],[10]]}
@Component({
- selector: 'app-host',
- templateUrl: './host.component.html',
- styleUrls: ['./host.component.css'],
- // provide the service
- providers: [{ provide: FlowerService, useValue: { emoji: '🌷' } }]
+selector: 'app-host',
+templateUrl: './host.component.html',
+styleUrls: ['./host.component.css'],
+// provide the service
+providers: [{ provide: FlowerService, useValue: { emoji: '🌷' } }]
})
export class HostComponent {
- // use host when injecting the service
- flower = inject(FlowerService, {host: true, optional: true});
+// use host when injecting the service
+flower = inject(FlowerService, {host: true, optional: true});
}
-
+```
-`HostComponent`に`host`オプションがあるため、`HostComponent`の親が`flower.emoji`にどのような値を持っていても、`HostComponent`はチューリップ🌷を使用します。
+`HostComponent`に`host`オプションがあるため、`HostComponent`の親が`flower.emoji`にどのような値を持っていても、`HostComponent`はチューリップ🌷を使用します。
-### Modifiers with constructor injection
+### コンストラクター注入での修飾子 {#modifiers-with-constructor-injection}
-Similarly as presented before, the behavior of constructor injection can be modified with `@Optional()`, `@Self()`, `@SkipSelf()` and `@Host()`.
+前に示したように、コンストラクター注入の動作は、`@Optional()`、`@Self()`、`@SkipSelf()`、および `@Host()` を使用して変更できます。
-Import each of them from `@angular/core` and use each in the component class constructor when you inject your service.
+`@angular/core` からそれぞれをインポートし、サービスを注入するときにコンポーネントクラスのコンストラクターでそれぞれを使用します。
-
+```ts {header:"src/app/self-no-data/self-no-data.component.ts" highlight:[3]}
export class SelfNoDataComponent {
constructor(@Self() @Optional() public leaf?: LeafService) { }
}
-
+```
-## テンプレートの論理構造
+## テンプレートの論理構造 {#logical-structure-of-the-template}
コンポーネントクラスでサービスを提供する場合、サービスは、サービスの提供場所と方法に応じて、 `ElementInjector` ツリー内で可視になります。
@@ -329,11 +329,11 @@ Angularテンプレートの基になる論理構造を理解すると、サー
コンポーネントは、次の例のようにテンプレートで使用されます。
-
+```html
;
-
+```
HELPFUL: 通常、コンポーネントとそのテンプレートは別々のファイルに宣言します。
注入システムの動作を理解するために、それらを組み合わせた論理ツリーの視点から見ると便利です。
@@ -342,29 +342,29 @@ HELPFUL: 通常、コンポーネントとそのテンプレートは別々の
以下は、 `` と `` のビューツリーを1つの論理ツリーに結合した例です。
-
+```html
<#VIEW>
<#VIEW>
- …ここにコンテンツが挿入されます…
+ …content goes here…
#VIEW>
#VIEW>
-
+```
`<#VIEW>` の区切りの考え方を理解することは、特にコンポーネントクラスでサービスを構成する場合に重要です。
-## 例: `@Component()` でサービスを提供する
+## 例: `@Component()` でサービスを提供する {#example-providing-services-in-component}
`@Component()`(または `@Directive()`)デコレーターを使用してサービスを提供する方法は、サービスの可視性を決めます。
-The following sections demonstrate `providers` and `viewProviders` along with ways to modify service visibility with `skipSelf` and `host`.
+次のセクションでは、`providers` と `viewProviders` について、および `skipSelf` と `host` を使用してサービスの可視性を変更する方法を説明します。
コンポーネントクラスでは、次の2つの方法でサービスを提供できます。
-| 配列 | 詳細 |
-|:--- |:--- |
+| 配列 | 詳細 |
+| :--------------------------- | :--------------------------------------------- |
| `providers` 配列を使用する | `@Component({ providers: [SomeService] })` |
| `viewProviders` 配列を使用する | `@Component({ viewProviders: [SomeService] })` |
@@ -375,49 +375,47 @@ The following sections demonstrate `providers` and `viewProviders` along with wa
論理ツリーでは、 `@Provide` 、 `@Inject` 、および `@ApplicationConfig` という特殊な属性が表示されます。
これらは実際の属性ではなく、内部で何が起こっているかを説明するためにここにあります。
-| Angular サービス属性 | 詳細 |
-|:--- |:--- |
-| `@Inject(Token)=>Value` | 論理ツリーのこの場所に `Token` が注入されている場合、その値は `Value` になります。 |
-| `@Provide(Token=Value)` | 論理ツリーのこの場所に `Token` が `Value` で提供されていることを示します。 |
-| `@ApplicationConfig` | この場所でフォールバック `EnvironmentInjector` を使用する必要があることを示します。 |
+| Angular サービス属性 | 詳細 |
+| :----------------------- | :------------------------------------------------------------------------------------- |
+| `@Inject(Token)=>Value` | 論理ツリーのこの場所に `Token` が注入されている場合、その値は `Value` になります。 |
+| `@Provide(Token=Value)` | 論理ツリーのこの場所に `Token` が `Value` で提供されていることを示します。 |
+| `@ApplicationConfig` | この場所でフォールバック `EnvironmentInjector` を使用する必要があることを示します。 |
-### アプリケーション構造の例
+### アプリケーション構造の例 {#example-app-structure}
-この例では、 `emoji` の値が赤いハイビスカス 🌺 である、 `root` に提供される `FlowerService` があります。
+この例では、 `emoji` の値が赤いハイビスカス 🌺 である、 `root` に提供される `FlowerService` があります。
-
+```ts {header:"src/app/flower.service.ts"}
@Injectable({
providedIn: 'root'
})
export class FlowerService {
- emoji = '🌺';
+ emoji = '🌺';
}
-
+```
`AppComponent` と `ChildComponent` のみが含まれるアプリケーションを検討してください。
最も基本的なレンダリングされたビューは、次のようなネストされたHTML要素のように見えます。
-
-
-
-
-
+```html
+
+
+
-
-
+```
ただし、裏側では、Angularはインジェクションリクエストを解決するときに、次のような論理ビュー表現を使用します。
-
-
+```html
+
<#VIEW>
-
+
<#VIEW>
#VIEW>
#VIEW>
-
+```
ここでの `<#VIEW>` は、テンプレートのインスタンスを表しています。
各コンポーネントには、独自の `<#VIEW>` があることに注意してください。
@@ -426,121 +424,117 @@ export class FlowerService {
次に、 `` が `FlowerService` を注入しているとします。
-
+```typescript
export class AppComponent {
flower = inject(FlowerService);
}
-
+```
結果を視覚化するために、 `` テンプレートにバインディングを追加します。
-
+```html
#VIEW>
#VIEW>
- #VIEW>
-
-
+#VIEW>
+
+```
-`` の投影されたコンテンツには、クジラ 🐳 が表示され、犬 🐶 は表示されません。これは、犬 🐶 が `` の `<#VIEW>` の内側にあるためです。
-`` は、 `<#VIEW>` の内側にある場合にのみ、犬 🐶 を表示できます。
+`` の投影されたコンテンツには、クジラ 🐳 が表示され、犬 🐶 は表示されません。これは、犬 🐶 が `` の `<#VIEW>` の内側にあるためです。
+`` は、 `<#VIEW>` の内側にある場合にのみ、犬 🐶 を表示できます。
-### 提供されたトークンの可視性
+### 提供されたトークンの可視性 {#visibility-of-provided-tokens}
可視性デコレーターは、論理ツリー内でインジェクショントークンの検索を開始する場所と終了する場所を制御します。
-To do this, place visibility configuration at the point of injection, that is, when invoking `inject()`, rather than at a point of declaration.
+これを行うには、宣言のポイントではなく、注入のポイント、つまり `inject()` を呼び出すときに可視性構成を配置します。
-To alter where the injector starts looking for `FlowerService`, add `skipSelf` to the `` `inject()` invocation where `FlowerService` is injected.
-This invocation is a property initializer the `` as shown in `child.component.ts`:
+インジェクターが `FlowerService` の検索を開始する場所を変更するには、`FlowerService` が注入される `` の `inject()` 呼び出しに `skipSelf` を追加します。
+この呼び出しは、`child.component.ts` に示すように、`` のプロパティ初期化子です。
-
+```typescript
flower = inject(FlowerService, { skipSelf: true })
-
+```
-With `skipSelf`, the `` injector doesn't look to itself for the `FlowerService`.
+`skipSelf` を使用すると、`` インジェクターは `FlowerService` を自分自身で探しません。
代わりに、インジェクターは `` の `ElementInjector` で `FlowerService` の検索を開始し、何も見つかりません。
-次に、 `` の `ModuleInjector` に戻り、 `` と `` が同じ `ModuleInjector` を共有しているため、赤いハイビスカス 🌺 値が見つかります。
+次に、 `` の `ModuleInjector` に戻り、 `` と `` が同じ `ModuleInjector` を共有しているため、赤いハイビスカス 🌺 値が見つかります。
UIには次のように表示されます。
-
-
-Emoji from FlowerService: 🌺
-
-
+```shell
+Emoji from FlowerService: 🌺
+```
論理ツリーでは、この同じ考え方は次のようになります。
-
-
+```html
"🌺">
- <#VIEW>
-
- <#VIEW @Inject(FlowerService, SkipSelf)=>"🌺">
-
- #VIEW>
-
- #VIEW>
-
+@Inject(FlowerService) flower=>"🌺">
+<#VIEW>
+
+<#VIEW @Inject(FlowerService, SkipSelf)=>"🌺">
-
+
-``がひまわり🌻を提供しているにもかかわらず、アプリケーションは赤いハイビスカス🌺をレンダリングします。これは、`skipSelf`が現在のインジェクター(`app-child`)に自身をスキップして親を探すよう指示するためです。
+#VIEW>
+
+#VIEW>
+
+```
+
+``がひまわり🌻を提供しているにもかかわらず、アプリケーションは赤いハイビスカス🌺をレンダリングします。これは、`skipSelf`が現在のインジェクター(`app-child`)に自身をスキップして親を探すよう指示するためです。
今度、(`skipSelf`に加えて)`host`を追加すると、結果は`null`になります。
これは、`host`が検索の上限を`app-child`の`<#VIEW>`に制限するためです。
論理ツリーでの考え方は次のとおりです。
-
-
+```html
"🌺">
- <#VIEW>
-
- <#VIEW inject(FlowerService, {skipSelf: true, host: true, optional:true})=>null>
- #VIEW>
-
- #VIEW>
+@Inject(FlowerService) flower=>"🌺">
+<#VIEW>
+
+<#VIEW inject(FlowerService, {skipSelf: true, host: true, optional:true})=>null>
+#VIEW>
+
+#VIEW>
+```
-
-
-Here, the services and their values are the same, but `host` stops the injector from looking any further than the `<#VIEW>` for `FlowerService`, so it doesn't find it and returns `null`.
+ここでは、サービスとその値は同じですが、`host` はインジェクターが `<#VIEW>` より先を `FlowerService` について探すのを止めるため、見つからずに `null` を返します。
-### `skipSelf` and `viewProviders`
+### `skipSelf` と `viewProviders` {#skipself-and-viewproviders}
-覚えておいてください。 `` は、 `viewProviders` 配列で `AnimalService` を提供し、その値は犬 🐶 です。
-インジェクターは、 `` の `ElementInjector` を `AnimalService` について調べるだけなので、クジラ 🐳 は見えません。
+覚えておいてください。 `` は、 `viewProviders` 配列で `AnimalService` を提供し、その値は犬 🐶 です。
+インジェクターは、 `` の `ElementInjector` を `AnimalService` について調べるだけなので、クジラ 🐳 は見えません。
-As in the `FlowerService` example, if you add `skipSelf` to the `inject()` of `AnimalService`, the injector won't look in the `ElementInjector` of the current `` for the `AnimalService`.
+`FlowerService` の例と同様に、`AnimalService` の `inject()` に `skipSelf` を追加すると、インジェクターは現在の `` の `ElementInjector` で `AnimalService` を探しません。
代わりに、インジェクターは `` の `ElementInjector` で検索を開始します。
-
+```typescript
@Component({
selector: 'app-child',
…
viewProviders: [
- { provide: AnimalService, useValue: { emoji: '🐶' } },
+ { provide: AnimalService, useValue: { emoji: '🐶' } },
],
})
-
-
-The logical tree looks like this with `skipSelf` in ``:
+```
-
+論理ツリーは、`` で `skipSelf` を使用すると次のようになります。
+```html
"🐳")>
- <#VIEW>
-
- <#VIEW @Provide(AnimalService="🐶")
- @Inject(AnimalService, SkipSelf=>"🐳")>
-
- #VIEW>
-
- #VIEW>
-
+@Inject(AnimalService=>"🐳")>
+<#VIEW>
+
+<#VIEW @Provide(AnimalService="🐶")
+@Inject(AnimalService, SkipSelf=>"🐳")>
-
+
+
+#VIEW>
+
+#VIEW>
+
+```
-``で`skipSelf`を使用すると、インジェクターは``の`ElementInjector`で`AnimalService`の検索を開始し、クジラ🐳を見つけます。
+``で`skipSelf`を使用すると、インジェクターは``の`ElementInjector`で`AnimalService`の検索を開始し、クジラ🐳を見つけます。
-### `host` and `viewProviders`
+### `host` と `viewProviders` {#host-and-viewproviders}
-`AnimalService`のインジェクションに`host`だけを使用する場合、インジェクターは``の`<#VIEW>`自体で`AnimalService`を見つけるため、結果は犬🐶になります。
+`AnimalService`のインジェクションに`host`だけを使用する場合、インジェクターは``の`<#VIEW>`自体で`AnimalService`を見つけるため、結果は犬🐶になります。
`ChildComponent`は`viewProviders`を設定し、犬の絵文字が`AnimalService`の値として提供されます。
`inject()`では`host`も使用できます:
-
+```typescript
@Component({
selector: 'app-child',
…
viewProviders: [
- { provide: AnimalService, useValue: { emoji: '🐶' } },
+ { provide: AnimalService, useValue: { emoji: '🐶' } },
]
})
export class ChildComponent {
animal = inject(AnimalService, { host: true })
}
-
-
-`host: true` causes the injector to look until it encounters the edge of the `<#VIEW>`.
+```
-
+`host: true` はインジェクターに `<#VIEW>` の端に遭遇するまで探すよう指示します。
+```html
"🐳")>
- <#VIEW>
-
- <#VIEW @Provide(AnimalService="🐶")
- inject(AnimalService, {host: true}=>"🐶")>
- #VIEW>
-
- #VIEW>
+@Inject(AnimalService=>"🐳")>
+<#VIEW>
+
+<#VIEW @Provide(AnimalService="🐶")
+inject(AnimalService, {host: true}=>"🐶")>
+#VIEW>
+
+#VIEW>
+```
-
-
-3番目の動物、ハリネズミ 🦔 を含む `viewProviders` 配列を、 `app.component.ts` の `@Component()` メタデータに追加します。
+3番目の動物、ハリネズミ 🦔 を含む `viewProviders` 配列を、 `app.component.ts` の `@Component()` メタデータに追加します。
-
+```typescript
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
viewProviders: [
- { provide: AnimalService, useValue: { emoji: '🦔' } },
+ { provide: AnimalService, useValue: { emoji: '🦔' } },
],
})
+```
-
-
-Next, add `skipSelf` along with `host` to the `inject()` for the `AnimalService` injection in `child.component.ts`.
-Here are `host` and `skipSelf` in the `animal` property initialization:
+次に、`child.component.ts` の `AnimalService` 注入の `inject()` に `host` とともに `skipSelf` を追加します。
+`animal` プロパティの初期化における `host` と `skipSelf` は次のとおりです。
-
+```typescript
export class ChildComponent {
animal = inject(AnimalService, { host: true, skipSelf: true });
}
-
-
+```
-When `host` and `skipSelf` were applied to the `FlowerService`, which is in the `providers` array, the result was `null` because `skipSelf` starts its search in the `` injector, but `host` stops searching at `<#VIEW>` —where there is no `FlowerService`
+`providers` 配列にある `FlowerService` に `host` と `skipSelf` を適用した場合、結果は `null` でした。これは、`skipSelf` が `` インジェクターで検索を開始しますが、`host` は `<#VIEW>` で検索を停止するためです。そこには `FlowerService` がありません。
論理ツリーでは、 `FlowerService` は `` で可視であり、 `<#VIEW>` では可視ではないことがわかります。
ただし、 `AppComponent` の `viewProviders` 配列で提供されている `AnimalService` は可視です。
論理ツリーの表現は、これが理由を示しています。
-
-
+```html
"🐳")>
- <#VIEW @Provide(AnimalService="🦔")
- @Inject(AnimalService, @Optional)=>"🦔">
-
-
- <#VIEW @Provide(AnimalService="🐶")
- inject(AnimalService, {skipSelf:true, host: true, optional: true})=>"🦔">
-
- #VIEW>
-
- #VIEW>
-
+@Inject(AnimalService=>"🐳")>
+<#VIEW @Provide(AnimalService="🦔")
+@Inject(AnimalService, @Optional)=>"🦔">
-
+
+
+<#VIEW @Provide(AnimalService="🐶")
+inject(AnimalService, {skipSelf:true, host: true, optional: true})=>"🦔">
+
+#VIEW>
+
+#VIEW>
+
+```
-`skipSelf`, causes the injector to start its search for the `AnimalService` at the ``, not the ``, where the request originates, and `host` stops the search at the `` `<#VIEW>`.
-`AnimalService` は `viewProviders` 配列を介して提供されるため、インジェクターは `<#VIEW>` でハリネズミ 🦔 を見つけます。
+`skipSelf` は、インジェクターがリクエストが発生した `` ではなく `` で `AnimalService` の検索を開始し、`host` は `` の `<#VIEW>` で検索を停止します。
+`AnimalService` は `viewProviders` 配列を介して提供されるため、インジェクターは `<#VIEW>` でハリネズミ 🦔 を見つけます。
-## 例: `ElementInjector` のユースケース
+## 例: `ElementInjector` のユースケース {#example-elementinjector-use-cases}
さまざまなレベルで1つ以上のプロバイダーを構成する機能により、便利な可能性が開かれます。
-### シナリオ:サービスの分離
+### シナリオ:サービスの分離 {#scenario-service-isolation}
アーキテクチャ上の理由から、サービスへのアクセスを属するアプリケーションドメインに制限する必要がある場合があります。
たとえば、悪役のリストを表示する `VillainsListComponent` を構築するとします。
@@ -966,22 +943,21 @@ When `host` and `skipSelf` were applied to the `FlowerService`, which is in the
代わりに、次のように `VillainsListComponent` の `providers` メタデータで `VillainsService` を提供する必要があります。
-
+```typescript
@Component({
- selector: 'app-villains-list',
- templateUrl: './villains-list.component.html',
- providers: [VillainsService]
+selector: 'app-villains-list',
+templateUrl: './villains-list.component.html',
+providers: [VillainsService]
})
export class VillainsListComponent {}
-
+```
`VillainsService` を `VillainsListComponent` メタデータで提供し、他の場所では提供しないと、サービスは `VillainsListComponent` とそのサブコンポーネントツリーのみに使用可能になります。
`VillainService` は、 `VillainsListComponent` に対してシングルトンです。なぜなら、それが宣言されている場所だからです。
`VillainsListComponent` が破棄されない限り `VillainService` のインスタンスは同じです。ただし `VillainsListComponent` のインスタンスが複数ある場合、 `VillainsListComponent` の各インスタンスには、独自の `VillainService` インスタンスが1つずつあります。
-### シナリオ:複数の編集セッション
+### シナリオ:複数の編集セッション {#scenario-multiple-edit-sessions}
多くのアプリケーションでは、ユーザーは同時に複数のオープンタスクで作業できます。
たとえば、税務申告の作成アプリケーションでは、作成者は複数の税務申告で作業し、1日を通してそれらを切り替えることができます。
@@ -993,9 +969,9 @@ export class VillainsListComponent {}
各税務申告コンポーネントには、次の機能があります。
-* 独自の税務申告の編集セッションを持ちます
-* 別のコンポーネントの申告に影響を与えずに税務申告を変更できます
-* 税務申告の変更を保存するか、キャンセルする機能があります
+- 独自の税務申告の編集セッションを持ちます
+- 別のコンポーネントの申告に影響を与えずに税務申告を変更できます
+- 税務申告の変更を保存するか、キャンセルする機能があります
`HeroTaxReturnComponent` に、変更を管理および復元するためのロジックがあるとします。
これは、ヒーローの税務申告にとっては簡単なタスクです。
@@ -1005,88 +981,88 @@ export class VillainsListComponent {}
`HeroTaxReturnService` は、単一の `HeroTaxReturn` をキャッシュし、その申告への変更を追跡し、保存または復元できます。
また、注入によって取得したアプリケーション全体のシングルトン `HeroService` に委任します。
-
+```typescript
import { Injectable } from '@angular/core';
import { HeroTaxReturn } from './hero';
import { HeroesService } from './heroes.service';
@Injectable()
export class HeroTaxReturnService {
- private currentTaxReturn!: HeroTaxReturn;
- private originalTaxReturn!: HeroTaxReturn;
+private currentTaxReturn!: HeroTaxReturn;
+private originalTaxReturn!: HeroTaxReturn;
- private heroService = inject(HeroesService);
+private heroService = inject(HeroesService);
- set taxReturn(htr: HeroTaxReturn) {
- this.originalTaxReturn = htr;
- this.currentTaxReturn = htr.clone();
- }
+set taxReturn(htr: HeroTaxReturn) {
+this.originalTaxReturn = htr;
+this.currentTaxReturn = htr.clone();
+}
- get taxReturn(): HeroTaxReturn {
- return this.currentTaxReturn;
- }
+get taxReturn(): HeroTaxReturn {
+return this.currentTaxReturn;
+}
- restoreTaxReturn() {
- this.taxReturn = this.originalTaxReturn;
- }
+restoreTaxReturn() {
+this.taxReturn = this.originalTaxReturn;
+}
- saveTaxReturn() {
- this.taxReturn = this.currentTaxReturn;
- this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe();
- }
+saveTaxReturn() {
+this.taxReturn = this.currentTaxReturn;
+this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe();
+}
}
-
+```
以下は、 `HeroTaxReturnService` を使用する `HeroTaxReturnComponent` です。
-
+```typescript
import { Component, EventEmitter, input, output } from '@angular/core';
import { HeroTaxReturn } from './hero';
import { HeroTaxReturnService } from './hero-tax-return.service';
@Component({
- selector: 'app-hero-tax-return',
- templateUrl: './hero-tax-return.component.html',
- styleUrls: [ './hero-tax-return.component.css' ],
- providers: [ HeroTaxReturnService ]
+selector: 'app-hero-tax-return',
+templateUrl: './hero-tax-return.component.html',
+styleUrls: [ './hero-tax-return.component.css' ],
+providers: [ HeroTaxReturnService ]
})
export class HeroTaxReturnComponent {
- message = '';
+message = '';
- close = output();
+close = output();
- get taxReturn(): HeroTaxReturn {
- return this.heroTaxReturnService.taxReturn;
- }
+get taxReturn(): HeroTaxReturn {
+return this.heroTaxReturnService.taxReturn;
+}
- taxReturn = input.required();
+taxReturn = input.required();
- constructor() {
- effect(() => {
- this.heroTaxReturnService.taxReturn = this.taxReturn();
- })
- }
+constructor() {
+effect(() => {
+this.heroTaxReturnService.taxReturn = this.taxReturn();
+})
+}
- private heroTaxReturnService = inject(HeroTaxReturnService);
+private heroTaxReturnService = inject(HeroTaxReturnService);
- onCanceled() {
- this.flashMessage('Canceled');
- this.heroTaxReturnService.restoreTaxReturn();
- }
+onCanceled() {
+this.flashMessage('Canceled');
+this.heroTaxReturnService.restoreTaxReturn();
+}
- onClose() { this.close.emit(); }
+onClose() { this.close.emit(); }
- onSaved() {
- this.flashMessage('Saved');
- this.heroTaxReturnService.saveTaxReturn();
- }
+onSaved() {
+this.flashMessage('Saved');
+this.heroTaxReturnService.saveTaxReturn();
+}
- flashMessage(msg: string) {
- this.message = msg;
- setTimeout(() => this.message = '', 500);
- }
+flashMessage(msg: string) {
+this.message = msg;
+setTimeout(() => this.message = '', 500);
+}
}
-
+```
_編集対象の税務申告_ は、 `input` プロパティを介して到着します。これは、ゲッターとセッターで実装されています。
セッターは、コンポーネント自身の `HeroTaxReturnService` インスタンスを、受信した申告で初期化します。
@@ -1098,9 +1074,9 @@ _編集対象の税務申告_ は、 `input` プロパティを介して到着
これを防ぐために、コンポーネントレベルのインジェクター `HeroTaxReturnComponent` を構成して、コンポーネントメタデータの `providers` プロパティを使用してサービスを提供します。
-
+```typescript
providers: [HeroTaxReturnService]
-
+```
`HeroTaxReturnComponent` には、 `HeroTaxReturnService` の独自の提供者がいます。
覚えておいてください。すべてのコンポーネントの _インスタンス_ には、独自のインジェクターがあります。
@@ -1108,7 +1084,7 @@ providers: [HeroTaxReturnService]
HELPFUL: シナリオコードの残りは、ドキュメントの他の場所で学習できる他のAngular機能とテクニックに依存しています。
-### シナリオ:特殊なプロバイダー
+### シナリオ:特殊なプロバイダー {#scenario-specialized-providers}
別のレベルでサービスを再度提供するもう1つの理由は、コンポーネントツリーのさらに深い場所で、そのサービスの _より特殊な_ 実装を置き換えるためです。
@@ -1141,9 +1117,9 @@ class COMPONENT_A,COMPONENT_B,COMPONENT_C noShadow
最も深いコンポーネント (C) で `Car` のインスタンスを解決すると、そのインジェクターは次を生成します。
-* インジェクター (C) によって解決された `Car` のインスタンス
-* インジェクター (B) によって解決された `Engine`
-* ルートインジェクター (A) によって解決された `Tires`。
+- インジェクター (C) によって解決された `Car` のインスタンス
+- インジェクター (B) によって解決された `Engine`
+- ルートインジェクター (A) によって解決された `Tires`。
```mermaid
graph BT;
@@ -1184,7 +1160,7 @@ style tires fill:#BDD7EE,color:#000
style RootInjector fill:#BDD7EE,color:#000
```
-## 依存性の注入の詳細
+## 依存性の注入の詳細 {#more-on-dependency-injection}
diff --git a/adev-ja/src/content/guide/di/lightweight-injection-tokens.en.md b/adev-ja/src/content/guide/di/lightweight-injection-tokens.en.md
index b20c8e31d3..d7fe0e79f0 100644
--- a/adev-ja/src/content/guide/di/lightweight-injection-tokens.en.md
+++ b/adev-ja/src/content/guide/di/lightweight-injection-tokens.en.md
@@ -1,7 +1,7 @@
# Optimizing client application size with lightweight injection tokens
This page provides a conceptual overview of a dependency injection technique that is recommended for library developers.
-Designing your library with *lightweight injection tokens* helps optimize the bundle size of client applications that use your library.
+Designing your library with _lightweight injection tokens_ helps optimize the bundle size of client applications that use your library.
You can manage the dependency structure among your components and injectable services to optimize bundle size by using tree-shakable providers.
This normally ensures that if a provided component or service is never actually used by the application, the compiler can remove its code from the bundle.
@@ -25,7 +25,7 @@ This component contains a body and can contain an optional header:
;
- …;
+…;
;
@@ -40,11 +40,11 @@ In a likely implementation, the `` component uses `@ContentChild()` or
class LibHeaderComponent {}
@Component({
- selector: 'lib-card',
- …,
+selector: 'lib-card',
+…,
})
class LibCardComponent {
- @ContentChild(LibHeaderComponent) header: LibHeaderComponent|null = null;
+@ContentChild(LibHeaderComponent) header: LibHeaderComponent|null = null;
}
@@ -57,13 +57,13 @@ This is because `LibCardComponent` actually contains two references to the `LibH
@ContentChild(LibHeaderComponent) header: LibHeaderComponent;
-* One of these reference is in the *type position*-- that is, it specifies `LibHeaderComponent` as a type: `header: LibHeaderComponent;`.
-* The other reference is in the *value position*-- that is, LibHeaderComponent is the value of the `@ContentChild()` parameter decorator: `@ContentChild(LibHeaderComponent)`.
+- One of these reference is in the _type position_-- that is, it specifies `LibHeaderComponent` as a type: `header: LibHeaderComponent;`.
+- The other reference is in the _value position_-- that is, LibHeaderComponent is the value of the `@ContentChild()` parameter decorator: `@ContentChild(LibHeaderComponent)`.
The compiler handles token references in these positions differently:
-* The compiler erases *type position* references after conversion from TypeScript, so they have no impact on tree-shaking.
-* The compiler must keep *value position* references at runtime, which **prevents** the component from being tree-shaken.
+- The compiler erases _type position_ references after conversion from TypeScript, so they have no impact on tree-shaking.
+- The compiler must keep _value position_ references at runtime, which **prevents** the component from being tree-shaken.
In the example, the compiler retains the `LibHeaderComponent` token that occurs in the value position.
This prevents the referenced component from being tree-shaken, even if the application does not actually use `` anywhere.
@@ -74,8 +74,8 @@ If `LibHeaderComponent` 's code, template, and styles combine to become too larg
The tree-shaking problem arises when a component is used as an injection token.
There are two cases when that can happen:
-* The token is used in the value position of a [content query](guide/components/queries#content-queries).
-* The token is used as a type specifier for constructor injection.
+- The token is used in the value position of a [content query](guide/components/queries#content-queries).
+- The token is used as a type specifier for constructor injection.
In the following example, both uses of the `OtherComponent` token cause retention of `OtherComponent`, preventing it from being tree-shaken when it is not used:
@@ -83,7 +83,7 @@ In the following example, both uses of the `OtherComponent` token cause retentio
class MyComponent {
constructor(@Optional() other: OtherComponent) {}
- @ContentChild(OtherComponent) other: OtherComponent|null;
+@ContentChild(OtherComponent) other: OtherComponent|null;
}
@@ -104,20 +104,20 @@ The following example shows how this works for the `LibHeaderComponent`:
abstract class LibHeaderToken {}
@Component({
- selector: 'lib-header',
- providers: [
- {provide: LibHeaderToken, useExisting: LibHeaderComponent}
- ]
- …,
+selector: 'lib-header',
+providers: [
+{provide: LibHeaderToken, useExisting: LibHeaderComponent}
+]
+…,
})
class LibHeaderComponent extends LibHeaderToken {}
@Component({
- selector: 'lib-card',
- …,
+selector: 'lib-card',
+…,
})
class LibCardComponent {
- @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
+@ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
}
@@ -152,30 +152,30 @@ abstract class LibHeaderToken {
}
@Component({
- selector: 'lib-header',
- providers: [
- {provide: LibHeaderToken, useExisting: LibHeaderComponent}
- ]
- …,
+selector: 'lib-header',
+providers: [
+{provide: LibHeaderToken, useExisting: LibHeaderComponent}
+]
+…,
})
class LibHeaderComponent extends LibHeaderToken {
- doSomething(): void {
- // Concrete implementation of `doSomething`
- }
+doSomething(): void {
+// Concrete implementation of `doSomething`
+}
}
@Component({
- selector: 'lib-card',
- …,
+selector: 'lib-card',
+…,
})
class LibCardComponent implement AfterContentInit {
- @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
+@ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
- ngAfterContentInit(): void {
- if (this.header !== null) {
- this.header?.doSomething();
- }
- }
+ngAfterContentInit(): void {
+if (this.header !== null) {
+this.header?.doSomething();
+}
+}
}
diff --git a/adev-ja/src/content/guide/di/lightweight-injection-tokens.md b/adev-ja/src/content/guide/di/lightweight-injection-tokens.md
index 0bf6405cd6..5239d4908f 100644
--- a/adev-ja/src/content/guide/di/lightweight-injection-tokens.md
+++ b/adev-ja/src/content/guide/di/lightweight-injection-tokens.md
@@ -1,7 +1,7 @@
# 軽量インジェクショントークンを使用したクライアントアプリケーションサイズの最適化
このページでは、ライブラリ開発者に推奨される依存性の注入テクニックの概要を概念的に説明します。
-*軽量インジェクショントークン* を使用してライブラリを設計すると、ライブラリを使用するクライアントアプリケーションのバンドルサイズを最適化できます。
+_軽量インジェクショントークン_ を使用してライブラリを設計すると、ライブラリを使用するクライアントアプリケーションのバンドルサイズを最適化できます。
ツリーシェイク可能なプロバイダーを使用することで、コンポーネントと注入可能なサービス間の依存関係の構造を管理してバンドルサイズを最適化できます。
通常、これにより、アプリケーションで実際に使用されていない提供されたコンポーネントまたはサービスが、コンパイラによってバンドルから削除されます。
@@ -25,7 +25,7 @@ Angularがインジェクショントークンを格納する方法により、
;
- …;
+…;
;
@@ -40,11 +40,11 @@ Angularがインジェクショントークンを格納する方法により、
class LibHeaderComponent {}
@Component({
- selector: 'lib-card',
- …,
+selector: 'lib-card',
+…,
})
class LibCardComponent {
- @ContentChild(LibHeaderComponent) header: LibHeaderComponent|null = null;
+@ContentChild(LibHeaderComponent) header: LibHeaderComponent|null = null;
}
@@ -57,13 +57,13 @@ class LibCardComponent {
@ContentChild(LibHeaderComponent) header: LibHeaderComponent;
-* これらの参照の1つは *型の位置* にあります。つまり、 `LibHeaderComponent` を型として指定します: `header: LibHeaderComponent;`。
-* もう1つの参照は *値の位置* にあります。つまり、LibHeaderComponentは `@ContentChild()` パラメータデコレーターの値です: `@ContentChild(LibHeaderComponent)`。
+- これらの参照の1つは _型の位置_ にあります。つまり、 `LibHeaderComponent` を型として指定します: `header: LibHeaderComponent;`。
+- もう1つの参照は _値の位置_ にあります。つまり、LibHeaderComponentは `@ContentChild()` パラメータデコレーターの値です: `@ContentChild(LibHeaderComponent)`。
コンパイラはこれらの位置にあるトークン参照を異なる方法で処理します。
-* コンパイラは、TypeScriptから変換した後の *型の位置* の参照を消去するため、ツリーシェイクには影響しません。
-* コンパイラは、*値の位置* の参照をランタイムに保持する必要があり、これが**妨げます** コンポーネントがツリーシェイクされること。
+- コンパイラは、TypeScriptから変換した後の _型の位置_ の参照を消去するため、ツリーシェイクには影響しません。
+- コンパイラは、_値の位置_ の参照をランタイムに保持する必要があり、これが**妨げます** コンポーネントがツリーシェイクされること。
この例では、コンパイラは値位置にある `LibHeaderComponent` トークンを保持します。
これにより、アプリケーションで実際に `` をどこでも使用していない場合でも、参照されるコンポーネントがツリーシェイクされることがなくなります。
@@ -74,8 +74,8 @@ class LibCardComponent {
ツリーシェイクの問題は、コンポーネントがインジェクショントークンとして使用されると発生します。
これは次の2つのケースで発生します。
-* トークンは、[コンテンツクエリ](guide/components/queries#content-queries)で値の位置で使用されます。
-* トークンは、コンストラクター注入の型指定子として使用されます。
+- トークンは、[コンテンツクエリ](guide/components/queries#content-queries)で値の位置で使用されます。
+- トークンは、コンストラクター注入の型指定子として使用されます。
次の例では、 `OtherComponent` トークンの両方の使用により、 `OtherComponent` が保持され、使用されていない場合にツリーシェイクされることがなくなります。
@@ -83,7 +83,7 @@ class LibCardComponent {
class MyComponent {
constructor(@Optional() other: OtherComponent) {}
- @ContentChild(OtherComponent) other: OtherComponent|null;
+@ContentChild(OtherComponent) other: OtherComponent|null;
}
@@ -104,20 +104,20 @@ HELPFUL: ライブラリは、[ツリーシェイク可能なプロバイダー]
abstract class LibHeaderToken {}
@Component({
- selector: 'lib-header',
- providers: [
- {provide: LibHeaderToken, useExisting: LibHeaderComponent}
- ]
- …,
+selector: 'lib-header',
+providers: [
+{provide: LibHeaderToken, useExisting: LibHeaderComponent}
+]
+…,
})
class LibHeaderComponent extends LibHeaderToken {}
@Component({
- selector: 'lib-card',
- …,
+selector: 'lib-card',
+…,
})
class LibCardComponent {
- @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
+@ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
}
@@ -152,30 +152,30 @@ abstract class LibHeaderToken {
}
@Component({
- selector: 'lib-header',
- providers: [
- {provide: LibHeaderToken, useExisting: LibHeaderComponent}
- ]
- …,
+selector: 'lib-header',
+providers: [
+{provide: LibHeaderToken, useExisting: LibHeaderComponent}
+]
+…,
})
class LibHeaderComponent extends LibHeaderToken {
- doSomething(): void {
- // Concrete implementation of `doSomething`
- }
+doSomething(): void {
+// Concrete implementation of `doSomething`
+}
}
@Component({
- selector: 'lib-card',
- …,
+selector: 'lib-card',
+…,
})
class LibCardComponent implement AfterContentInit {
- @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
+@ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
- ngAfterContentInit(): void {
- if (this.header !== null) {
- this.header?.doSomething();
- }
- }
+ngAfterContentInit(): void {
+if (this.header !== null) {
+this.header?.doSomething();
+}
+}
}
diff --git a/adev-ja/src/content/guide/di/overview.en.md b/adev-ja/src/content/guide/di/overview.en.md
index 1620a7edcb..03de6b1889 100644
--- a/adev-ja/src/content/guide/di/overview.en.md
+++ b/adev-ja/src/content/guide/di/overview.en.md
@@ -1,29 +1,154 @@
-"DI" is a design pattern and mechanism for creating and delivering some parts of an app to other parts of an app that require them.
+
+Dependency Injection (DI) is a design pattern used to organize and share code across an application.
TIP: Check out Angular's [Essentials](essentials/dependency-injection) before diving into this comprehensive guide.
-When you develop a smaller part of your system, like a module or a class, you may need to use features from other classes. For example, you may need an HTTP service to make backend calls. Dependency Injection, or DI, is a design pattern and mechanism for creating and delivering some parts of an application to other parts of an application that require them. Angular supports this design pattern and you can use it in your applications to increase flexibility and modularity.
-
-In Angular, dependencies are typically services, but they also can be values, such as strings or functions. An injector for an application (created automatically during bootstrap) instantiates dependencies when needed, using a configured provider of the service or value.
-
-## Learn about Angular dependency injection
-
-
-
- Learn basic principles of dependency injection in Angular.
-
-
- Describes how to create a service and inject it in other services and components.
-
-
- Describes how to configure dependencies using the providers field on the @Component and @NgModule decorators. Also describes how to use InjectionToken to provide and inject values in DI, which can be helpful when you want to use a value other than classes as dependencies.
-
-
- Describes what an injection context is and how to use the DI system where you need it.
-
-
- Hierarchical DI enables you to share dependencies between different parts of the application only when and if you need to. This is an advanced topic.
-
-
+As an application grows, developers often need to reuse and share features across different parts of the codebase. [Dependency Injection (DI)](https://en.wikipedia.org/wiki/Dependency_injection) is a design pattern used to organize and share code across an application by allowing you to "inject" features into different parts.
+
+Dependency injection is a popular pattern because it allows developers to address common challenges such as:
+
+- **Improved code maintainability**: Dependency injection allows cleaner separation of concerns which enables easier refactoring and reducing code duplication.
+- **Scalability**: Modular functionality can be reused across multiple contexts and allows for easier scaling.
+- **Better testing**: DI allows unit tests to easily use [test doubles](https://en.wikipedia.org/wiki/Test_double) for situations when using a real implementation is not practical.
+
+## How does dependency injection work in Angular?
+
+A dependency is any object, value, function or service that a class needs to work but does not create itself. In other words, it creates a relationship between different parts of your application since it wouldn't work without the dependency.
+
+There are two ways that code interacts with any dependency injection system:
+
+- Code can _provide_, or make available, values.
+- Code can _inject_, or ask for, those values as dependencies.
+
+"Values," in this context, can be any JavaScript value, including objects and functions. Common types of injected dependencies include:
+
+- **Configuration values**: Environment-specific constants, API URLs, feature flags, etc.
+- **Factories**: Functions that create objects or values based on runtime conditions
+- **Services**: Classes that provide common functionality, business logic, or state
+
+Angular components and directives automatically participate in DI, meaning that they can inject dependencies _and_ they are available to be injected.
+
+## What are services?
+
+An Angular _service_ is a TypeScript class decorated with `@Injectable`, which makes an instance of the class available to be injected as a dependency. Services are the most common way of sharing data and functionality across an application.
+
+Common types of services include:
+
+- **Data clients:** Abstracts the details of making requests to a server for data retrieval and mutation
+- **State management:** Defines state shared across multiple components or pages
+- **Authentication and authorization:** Manages user authentication, token storage, and access control
+- **Logging and error handling:** Establishes a common API for logging or communicating error states to the user
+- **Event handling and dispatch:** Handles events or notifications that are not associated with a specific component, or for dispatching events and notifications to components, following the [observer pattern](https://en.wikipedia.org/wiki/Observer_pattern)
+- **Utility functions:** Offers reusable utility functions like data formatting, validation, or calculations
+
+The following example declares a service named `AnalyticsLogger`:
+
+```ts
+import { Injectable } from '@angular/core';
+
+@Injectable({ providedIn: 'root' })
+export class AnalyticsLogger {
+ trackEvent(category: string, value: string) {
+ console.log('Analytics event logged:', {
+ category,
+ value,
+ timestamp: new Date().toISOString()
+ })
+ }
+}
+```
+
+NOTE: The `providedIn: 'root'` option makes this service available throughout your entire application as a singleton. This is the recommended approach for most services.
+
+## Injecting dependencies with `inject()`
+
+You can inject dependencies using Angular's `inject()` function.
+
+Here is an example of a navigation bar that injects `AnalyticsLogger` and Angular `Router` service to allow users to navigate to a different page while tracking the event.
+
+```angular-ts
+import { Component, inject } from '@angular/core';
+import { Router } from '@angular/router';
+import { AnalyticsLogger } from './analytics-logger';
+
+@Component({
+ selector: 'app-navbar',
+ template: `
+ Detail Page
+ `,
+})
+export class NavbarComponent {
+ private router = inject(Router);
+ private analytics = inject(AnalyticsLogger);
+
+ navigateToDetail(event: Event) {
+ event.preventDefault();
+ this.analytics.trackEvent('navigation', '/details');
+ this.router.navigate(['/details']);
+ }
+}
+```
+
+### Where can `inject()` be used?
+
+You can inject dependencies during construction of a component, directive, or service. The call to `inject` can appear in either the `constructor` or in a field initializer. Here are some common examples:
+
+```ts
+@Component({...})
+export class MyComponent {
+ // ✅ In class field initializer
+ private service = inject(MyService);
+
+ // ✅ In constructor body
+ private anotherService: MyService;
+
+ constructor() {
+ this.anotherService = inject(MyService);
+ }
+}
+```
+
+```ts
+@Directive({...})
+export class MyDirective {
+ // ✅ In class field initializer
+ private element = inject(ElementRef);
+}
+```
+
+```ts
+import { Injectable, inject } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+
+@Injectable({ providedIn: 'root' })
+export class MyService {
+ // ✅ In a service
+ private http = inject(HttpClient);
+}
+```
+
+```ts
+export const authGuard = () => {
+ // ✅ In a route guard
+ const auth = inject(AuthService);
+ return auth.isAuthenticated();
+}
+```
+
+Angular uses the term "injection context" to describe any place in your code where you can call `inject`. While component, directive, and service construction is the most common, see [injection contexts](/guide/di/dependency-injection-context) for more details.
+
+For more information, see the [inject API docs](api/core/inject#usage-notes).
+
+## Next steps
+
+Now that you understand the fundamentals of dependency injection in Angular, you're ready to learn how to create your own services.
+
+The next guide, [Creating and using services](guide/di/creating-and-using-services), will show you:
+
+- How to create a service with the Angular CLI or manually
+- How the `providedIn: 'root'` pattern works
+- How to inject services into components and other services
+
+This covers the most common use case for services in Angular applications.
diff --git a/adev-ja/src/content/guide/di/overview.md b/adev-ja/src/content/guide/di/overview.md
index 6d1c861347..66f66e9f83 100644
--- a/adev-ja/src/content/guide/di/overview.md
+++ b/adev-ja/src/content/guide/di/overview.md
@@ -1,29 +1,154 @@
-"DI" は、アプリケーションの一部を作成して、それらを必要とするアプリケーションの他の部分に提供するための設計パターンとメカニズムです。
+
+依存性の注入 (DI) は、アプリケーション全体でコードを整理し共有するために使用される設計パターンです。
-TIP: この包括的なガイドに取り組む前に、Angularの [基本概念](essentials/dependency-injection) を確認してください。
-
-モジュールやクラスなどのシステムのより小さな部分を開発する場合、他のクラスの機能を使用する必要がある場合があります。たとえば、バックエンドを呼び出すためにHTTPサービスが必要になる場合があります。依存性の注入 (DI) は、アプリケーションの一部を作成して、それらを必要とするアプリケーションの他の部分に提供するための設計パターンとメカニズムです。Angularはこの設計パターンをサポートしており、アプリケーションでこれを利用することで、柔軟性とモジュール性を高めることができます。
-
-Angularでは、依存関係は通常サービスですが、文字列や関数などの値となることもあります。アプリケーションのインジェクター(ブートストラップ時に自動的に作成されます)は、サービスまたは値の構成されたプロバイダーを使用して、必要に応じて依存関係をインスタンス化します。
-
-## Angular の依存性の注入について学ぶ
-
-
-
- Angularの依存性の注入の基本原則を学びます。
-
-
- サービスを作成し、他のサービスやコンポーネントに注入する方法について説明します。
-
-
- `@Component` および `@NgModule` デコレーターの `providers` フィールドを使用して依存関係を構成する方法について説明します。また、InjectionToken を使用して DI で値を提供および注入する方法についても説明します。これは、クラス以外の値を依存関係として使用する場合に役立ちます。
-
-
- 注入コンテキストとは何か、DI システムを必要とする場所にどのように使用するかについて説明します。
-
-
- 階層型 DI を使用すると、必要に応じてのみアプリケーションのさまざまな部分間で依存関係を共有できます。これは高度なトピックです。
-
-
+TIP: この包括的なガイドに取り組む前に、Angularの [基本ガイド](essentials/dependency-injection) を確認してください。
+
+アプリケーションが成長するにつれて、開発者はコードベースのさまざまな部分で機能を再利用し共有する必要がでてきます。[依存性の注入 (DI)](https://en.wikipedia.org/wiki/Dependency_injection) は、さまざまな部分に機能を「注入」できるようにすることで、アプリケーション全体でコードを整理し共有するために使用される設計パターンです。
+
+依存性の注入は、開発者が次のような一般的な課題に対処できるため、人気のあるパターンです。
+
+- **コードの保守性の向上**: 依存性の注入により、関心事をよりクリーンに分離でき、リファクタリングを容易にし、コードの重複を減らせます。
+- **スケーラビリティ**: モジュール化された機能を複数のコンテキストで再利用でき、スケーリングが容易になります。
+- **テストの改善**: DIを使用すると、実際の実装を使用することが実用的でない状況で、ユニットテストが簡単に[テストダブル](https://en.wikipedia.org/wiki/Test_double)を使用できるようになります。
+
+## Angularでの依存性の注入の仕組み {#how-does-dependency-injection-work-in-angular}
+
+依存関係とは、クラスが動作するために必要であるが、自分自身では作成しないオブジェクト、値、関数、またはサービスのことです。言い換えれば、依存関係がなければ機能しないため、アプリケーションのさまざまな部分間の関係を作成します。
+
+コードが依存性の注入システムとやり取りする方法は2つあります。
+
+- コードは値を _提供_ (利用可能にする) できます。
+- コードは依存関係としてそれらの値を _注入_ (要求) できます。
+
+この文脈での「値」とは、オブジェクトや関数を含む任意のJavaScriptの値です。注入される依存関係の一般的なタイプには次のものがあります。
+
+- **設定値**: 環境固有の定数、API URL、機能フラグなど
+- **ファクトリー**: 実行時の条件に基づいてオブジェクトまたは値を作成する関数
+- **サービス**: 共通の機能、ビジネスロジック、または状態を提供するクラス
+
+AngularのコンポーネントとディレクティブはDIに自動的に参加します。つまり、依存関係を注入でき、_かつ_ 注入される対象として利用可能になります。
+
+## サービスとは {#what-are-services}
+
+Angular _サービス_ は `@Injectable` で装飾されたTypeScriptクラスで、クラスのインスタンスを依存関係として注入できるようにします。サービスは、アプリケーション全体でデータと機能を共有する最も一般的な方法です。
+
+サービスの一般的なタイプには次のものがあります。
+
+- **データクライアント:** データの取得と変更のためにサーバーへのリクエストを行う詳細を抽象化します
+- **状態管理:** 複数のコンポーネントまたはページ間で共有される状態を定義します
+- **認証と認可:** ユーザー認証、トークンストレージ、アクセス制御を管理します
+- **ロギングとエラー処理:** ユーザーにエラー状態をログ記録または通知するための共通APIを確立します
+- **イベント処理とディスパッチ:** 特定のコンポーネントに関連付けられていないイベントや通知を処理したり、[オブザーバーパターン](https://en.wikipedia.org/wiki/Observer_pattern)に従ってコンポーネントにイベントや通知をディスパッチしたりします
+- **ユーティリティ関数:** データフォーマット、検証、計算などの再利用可能なユーティリティ関数を提供します
+
+次の例は、`AnalyticsLogger` という名前のサービスを宣言しています。
+
+```ts
+import { Injectable } from '@angular/core';
+
+@Injectable({ providedIn: 'root' })
+export class AnalyticsLogger {
+ trackEvent(category: string, value: string) {
+ console.log('Analytics event logged:', {
+ category,
+ value,
+ timestamp: new Date().toISOString()
+ })
+ }
+}
+```
+
+NOTE: `providedIn: 'root'` オプションにより、このサービスはシングルトンとしてアプリケーション全体で利用可能になります。これはほとんどのサービスで推奨されるアプローチです。
+
+## `inject()` による依存性の注入 {#injecting-dependencies-with-inject}
+
+Angularの `inject()` 関数を使用して依存関係を注入できます。
+
+次は、`AnalyticsLogger` とAngularの `Router` サービスを注入して、イベントを追跡しながらユーザーが別のページに移動できるようにするナビゲーションバーの例です。
+
+```angular-ts
+import { Component, inject } from '@angular/core';
+import { Router } from '@angular/router';
+import { AnalyticsLogger } from './analytics-logger';
+
+@Component({
+ selector: 'app-navbar',
+ template: `
+ Detail Page
+ `,
+})
+export class NavbarComponent {
+ private router = inject(Router);
+ private analytics = inject(AnalyticsLogger);
+
+ navigateToDetail(event: Event) {
+ event.preventDefault();
+ this.analytics.trackEvent('navigation', '/details');
+ this.router.navigate(['/details']);
+ }
+}
+```
+
+### `inject()` はどこで使用できるか {#where-can-inject-be-used}
+
+コンポーネント、ディレクティブ、またはサービスの構築中に依存関係を注入できます。`inject` の呼び出しは、`constructor` またはフィールドイニシャライザーのいずれかに配置できます。一般的な例をいくつか示します。
+
+```ts
+@Component({...})
+export class MyComponent {
+ // ✅ クラスフィールドイニシャライザー内
+ private service = inject(MyService);
+
+ // ✅ コンストラクター本体内
+ private anotherService: MyService;
+
+ constructor() {
+ this.anotherService = inject(MyService);
+ }
+}
+```
+
+```ts
+@Directive({...})
+export class MyDirective {
+ // ✅ クラスフィールドイニシャライザー内
+ private element = inject(ElementRef);
+}
+```
+
+```ts
+import { Injectable, inject } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+
+@Injectable({ providedIn: 'root' })
+export class MyService {
+ // ✅ サービス内
+ private http = inject(HttpClient);
+}
+```
+
+```ts
+export const authGuard = () => {
+ // ✅ ルートガード内
+ const auth = inject(AuthService);
+ return auth.isAuthenticated();
+}
+```
+
+Angularは「注入コンテキスト」という用語を使用して、コード内で `inject` を呼び出せる場所を説明します。コンポーネント、ディレクティブ、サービスの構築が最も一般的ですが、詳細については[注入コンテキスト](/guide/di/dependency-injection-context)を参照してください。
+
+詳細については、[inject APIドキュメント](api/core/inject#usage-notes)を参照してください。
+
+## 次のステップ {#next-steps}
+
+Angularにおける依存性の注入の基本を理解したので、独自のサービスを作成する方法を学ぶ準備ができました。
+
+次のガイド [サービスの作成と使用](guide/di/creating-and-using-services) では、次のことを学びます。
+
+- Angular CLIまたは手動でサービスを作成する方法
+- `providedIn: 'root'` パターンの仕組み
+- サービスをコンポーネントや他のサービスに注入する方法
+
+これは、Angularアプリケーションでサービスを使用する最も一般的なユースケースをカバーしています。
diff --git a/adev-ja/src/content/guide/directives/attribute-directives.en.md b/adev-ja/src/content/guide/directives/attribute-directives.en.md
index 69403a04e9..4d39ac9419 100644
--- a/adev-ja/src/content/guide/directives/attribute-directives.en.md
+++ b/adev-ja/src/content/guide/directives/attribute-directives.en.md
@@ -8,36 +8,34 @@ This section walks you through creating a highlight directive that sets the back
1. To create a directive, use the CLI command [`ng generate directive`](tools/cli/schematics).
-
+ ```shell
+ ng generate directive highlight
+ ```
- ng generate directive highlight
+ The CLI creates `src/app/highlight.directive.ts`, a corresponding test file `src/app/highlight.directive.spec.ts`.
-
+
- The CLI creates `src/app/highlight.directive.ts`, a corresponding test file `src/app/highlight.directive.spec.ts`.
-
-
-
- The `@Directive()` decorator's configuration property specifies the directive's CSS attribute selector, `[appHighlight]`.
+ The `@Directive()` decorator's configuration property specifies the directive's CSS attribute selector, `[appHighlight]`.
1. Import `ElementRef` from `@angular/core`.
- `ElementRef` grants direct access to the host DOM element through its `nativeElement` property.
+ `ElementRef` grants direct access to the host DOM element through its `nativeElement` property.
1. Add `ElementRef` in the directive's `constructor()` to [inject](guide/di) a reference to the host DOM element, the element to which you apply `appHighlight`.
1. Add logic to the `HighlightDirective` class that sets the background to yellow.
-
+
-HELPFUL: Directives *do not* support namespaces.
+HELPFUL: Directives _do not_ support namespaces.
-
+
## Applying an attribute directive
1. To use the `HighlightDirective`, add a `
` element to the HTML template with the directive as an attribute.
-
+
Angular creates an instance of the `HighlightDirective` class and injects a reference to the `
` element into the directive's constructor, which sets the `
` element's background style to yellow.
@@ -45,21 +43,21 @@ Angular creates an instance of the `HighlightDirective` class and injects a refe
This section shows you how to detect when a user mouses into or out of the element and to respond by setting or clearing the highlight color.
-1. Import `HostListener` from '@angular/core'.
+1. Configure host event bindings using the `host` property in the `@Directive()` decorator.
-
+
-1. Add two event handlers that respond when the mouse enters or leaves, each with the `@HostListener()` decorator.
+1. Add two event handler methods, and map host element events to them via the `host` property.
-
+
-Subscribe to events of the DOM element that hosts an attribute directive, the `
` in this case, with the `@HostListener()` decorator.
+Subscribe to events of the DOM element that hosts an attribute directive (the `
` in this case) by configuring event listeners on the directive's [`host` property](guide/components/host-elements#binding-to-the-host-element).
HELPFUL: The handlers delegate to a helper method, `highlight()`, that sets the color on the host DOM element, `el`.
The complete directive is as follows:
-
+
The background color appears when the pointer hovers over the paragraph element and disappears as the pointer moves out.
@@ -71,26 +69,25 @@ This section walks you through setting the highlight color while applying the `H
1. In `highlight.directive.ts`, import `Input` from `@angular/core`.
-
-
-1. Add an `appHighlight` `input` property.
+
-
+2. Add an `appHighlight` `input` property.
- The `input()` function adds metadata to the class that makes the directive's `appHighlight` property available for binding.
+
-2. In `app.component.ts`, add a `color` property to the `AppComponent`.
+ The `input()` function adds metadata to the class that makes the directive's `appHighlight` property available for binding.
-
+3. In `app.component.ts`, add a `color` property to the `AppComponent`.
-3. To simultaneously apply the directive and the color, use property binding with the `appHighlight` directive selector, setting it equal to `color`.
+
-
+4. To simultaneously apply the directive and the color, use property binding with the `appHighlight` directive selector, setting it equal to `color`.
- The `[appHighlight]` attribute binding performs two tasks:
+
- * Applies the highlighting directive to the `
` element
- * Sets the directive's highlight color with a property binding
+ The `[appHighlight]` attribute binding performs two tasks:
+ - Applies the highlighting directive to the `
` element
+ - Sets the directive's highlight color with a property binding
### Setting the value with user input
@@ -98,38 +95,38 @@ This section guides you through adding radio buttons to bind your color choice t
1. Add markup to `app.component.html` for choosing a color as follows:
-
+
1. Revise the `AppComponent.color` so that it has no initial value.
-
+
1. In `highlight.directive.ts`, revise `onMouseEnter` method so that it first tries to highlight with `appHighlight` and falls back to `red` if `appHighlight` is `undefined`.
-
+
1. Serve your application to verify that the user can choose the color with the radio buttons.
-
+
## Binding to a second property
This section guides you through configuring your application so the developer can set the default color.
-1. Add a second `Input()` property to `HighlightDirective` called `defaultColor`.
+1. Add a second `input()` property to `HighlightDirective` called `defaultColor`.
-
+
1. Revise the directive's `onMouseEnter` so that it first tries to highlight with the `appHighlight`, then with the `defaultColor`, and falls back to `red` if both properties are `undefined`.
-
+
1. To bind to the `AppComponent.color` and fall back to "violet" as the default color, add the following HTML.
- In this case, the `defaultColor` binding doesn't use square brackets, `[]`, because it is static.
+ In this case, the `defaultColor` binding doesn't use square brackets, `[]`, because it is static.
-
+
- As with components, you can add multiple directive property bindings to a host element.
+ As with components, you can add multiple directive property bindings to a host element.
The default color is red if there is no default color binding.
When the user chooses a color the selected color becomes the active highlight color.
@@ -143,12 +140,12 @@ To prevent expression evaluation in the browser, add `ngNonBindable` to the host
In the following example, the expression `{{ 1 + 1 }}` renders just as it does in your code editor, and does not display `2`.
-
+
Applying `ngNonBindable` to an element stops binding for that element's child elements.
However, `ngNonBindable` still lets directives work on the element where you apply `ngNonBindable`.
In the following example, the `appHighlight` directive is still active but Angular does not evaluate the expression `{{ 1 + 1 }}`.
-
+
If you apply `ngNonBindable` to a parent element, Angular disables interpolation and binding of any sort, such as property binding or event binding, for the element's children.
diff --git a/adev-ja/src/content/guide/directives/attribute-directives.md b/adev-ja/src/content/guide/directives/attribute-directives.md
index c693c23007..cc312ad4e1 100644
--- a/adev-ja/src/content/guide/directives/attribute-directives.md
+++ b/adev-ja/src/content/guide/directives/attribute-directives.md
@@ -8,36 +8,34 @@
1. ディレクティブを作成するには、CLIコマンド[`ng generate directive`](tools/cli/schematics)を使用します。
-
+ ```shell
+ ng generate directive highlight
+ ```
- ng generate directive highlight
+ CLIは`src/app/highlight.directive.ts`と、対応するテストファイル`src/app/highlight.directive.spec.ts`を作成します。
-
+
- CLIは`src/app/highlight.directive.ts`と、対応するテストファイル`src/app/highlight.directive.spec.ts`を作成します。
-
-
-
- `@Directive()`デコレーターの構成プロパティは、ディレクティブのCSS属性セレクター`[appHighlight]`を指定します。
+ `@Directive()`デコレーターの構成プロパティは、ディレクティブのCSS属性セレクター`[appHighlight]`を指定します。
1. `@angular/core`から`ElementRef`をインポートします。
- `ElementRef`は、`nativeElement`プロパティを通じてホストDOM要素(`appHighlight`を適用する要素)への直接アクセスを提供します。
+ `ElementRef`は、`nativeElement`プロパティを通じてホストDOM要素への直接アクセスを提供します。
-1. ディレクティブの`constructor()`に`ElementRef`を追加して、ホストDOM要素への参照を[注入](guide/di)します。
+1. ディレクティブの`constructor()`に`ElementRef`を追加して、`appHighlight`を適用する要素であるホストDOM要素への参照を[注入](guide/di)します。
1. 背景を黄色に設定するロジックを`HighlightDirective`クラスに追加します。
-
+
-HELPFUL: ディレクティブは*ネームスペース*をサポートしていません。
+HELPFUL: ディレクティブは_ネームスペース_をサポートしていません。
-
+
## 属性ディレクティブの適用
1. `HighlightDirective`を使用するには、ディレクティブを属性として持つ`
`要素にハイライトディレクティブを適用する
+ - プロパティバインディングを使用してディレクティブのハイライトカラーを設定する
### ユーザー入力を使用して値を設定する
@@ -98,38 +95,38 @@ HELPFUL: ハンドラーは、ホストDOM要素`el`に色を設定するヘル
1. 色を選択するためのマークアップを`app.component.html`に追加します。
-
+
1. `AppComponent.color`を修正して、初期値を持たないようにします。
-
+
1. `highlight.directive.ts`で、`onMouseEnter`メソッドを修正して、最初に`appHighlight`でハイライトしようとします。`appHighlight`が`undefined`の場合は`red`にフォールバックします。
-
+
1. アプリケーションを起動して、ユーザーがラジオボタンで色を選択できることを確認します。
-
+
## 2番目のプロパティにバインドする
このセクションでは、開発者がデフォルトカラーを設定できるようにアプリケーションを構成する方法について説明します。
-1. `HighlightDirective`に`defaultColor`という名前の2番目の`Input()`プロパティを追加します。
+1. `HighlightDirective`に`defaultColor`という名前の2番目の`input()`プロパティを追加します。
-
+
1. ディレクティブの`onMouseEnter`を修正して、最初に`appHighlight`でハイライトしようとします。次に`defaultColor`でハイライトしようとします。両方のプロパティが`undefined`の場合は`red`にフォールバックします。
-
+
1. `AppComponent.color`にバインドし、デフォルトカラーとして「violet」を使用するには、次のHTMLを追加します。
- この場合、`defaultColor`バインディングは、静的であるため、角括弧`[]`を使用しません。
+ この場合、`defaultColor`バインディングは、静的であるため、角括弧`[]`を使用しません。
-
+
- コンポーネントと同様に、ホスト要素に複数のディレクティブプロパティバインディングを追加できます。
+ コンポーネントと同様に、ホスト要素に複数のディレクティブプロパティバインディングを追加できます。
デフォルトカラーは、デフォルトカラーバインディングがない場合は赤です。
ユーザーが色を選択すると、選択した色がアクティブなハイライトカラーになります。
@@ -143,12 +140,12 @@ HELPFUL: ハンドラーは、ホストDOM要素`el`に色を設定するヘル
次の例では、式`{{ 1 + 1 }}`はコードエディタと同じようにレンダリングされ、`2`は表示されません。
-
+
`ngNonBindable`を要素に適用すると、その要素の子要素のバインディングが停止します。
ただし、`ngNonBindable`は、`ngNonBindable`を適用した要素に対しては、ディレクティブを動作させます。
次の例では、`appHighlight`ディレクティブはアクティブですが、Angularは式`{{ 1 + 1 }}`を評価しません。
-
+
`ngNonBindable`を親要素に適用すると、Angularは要素の子要素に対して、プロパティバインディングやイベントバインディングなどあらゆる種類の補間とバインディングを無効にします。
diff --git a/adev-ja/src/content/guide/directives/directive-composition-api.en.md b/adev-ja/src/content/guide/directives/directive-composition-api.en.md
index c898326894..53694c00b4 100644
--- a/adev-ja/src/content/guide/directives/directive-composition-api.en.md
+++ b/adev-ja/src/content/guide/directives/directive-composition-api.en.md
@@ -3,13 +3,13 @@
Angular directives offer a great way to encapsulate reusable behaviors— directives can apply
attributes, CSS classes, and event listeners to an element.
-The *directive composition API* lets you apply directives to a component's host element from
-*within* the component TypeScript class.
+The _directive composition API_ lets you apply directives to a component's host element from
+_within_ the component TypeScript class.
## Adding directives to a component
You apply directives to a component by adding a `hostDirectives` property to a component's
-decorator. We call such directives *host directives*.
+decorator. We call such directives _host directives_.
In this example, we apply the directive `MenuBehavior` to the host element of `AdminMenu`. This
works similarly to applying the `MenuBehavior` to the `` element in a template.
diff --git a/adev-ja/src/content/guide/directives/directive-composition-api.md b/adev-ja/src/content/guide/directives/directive-composition-api.md
index a8036dbfc1..dcebf9cf36 100644
--- a/adev-ja/src/content/guide/directives/directive-composition-api.md
+++ b/adev-ja/src/content/guide/directives/directive-composition-api.md
@@ -1,4 +1,4 @@
-## ディレクティブ合成API
+# ディレクティブ合成API
Angularディレクティブは、再利用可能な動作をカプセル化する素晴らしい方法を提供します。
ディレクティブは、属性、CSSクラス、およびイベントリスナーを要素に適用できます。
diff --git a/adev-ja/src/content/guide/directives/overview.en.md b/adev-ja/src/content/guide/directives/overview.en.md
index 07a62d2c98..2ea704759e 100644
--- a/adev-ja/src/content/guide/directives/overview.en.md
+++ b/adev-ja/src/content/guide/directives/overview.en.md
@@ -38,7 +38,7 @@ HELPFUL: To add or remove a _single_ class, use [class binding](guide/templates/
To use `NgClass`, add it to the component's `imports` list.
-
+
### Using `NgClass` with an expression
@@ -46,7 +46,7 @@ On the element you'd like to style, add `[ngClass]` and set it equal to an expre
In this case, `isSpecial` is a boolean set to `true` in `app.component.ts`.
Because `isSpecial` is true, `ngClass` applies the class of `special` to the `
`.
-
+
### Using `NgClass` with a method
@@ -57,11 +57,11 @@ Because `isSpecial` is true, `ngClass` applies the class of `special` to the `
+
1. In the template, add the `ngClass` property binding to `currentClasses` to set the element's classes:
-
+
For this use case, Angular applies the classes on initialization and in case of changes caused by reassigning the `currentClasses` object.
The full example calls `setCurrentClasses()` initially with `ngOnInit()` when the user clicks on the `Refresh currentClasses` button.
@@ -75,7 +75,7 @@ HELPFUL: To add or remove a _single_ style, use [style bindings](guide/templates
To use `NgStyle`, add it to the component's `imports` list.
-
+
Use `NgStyle` to set multiple inline styles simultaneously, based on the state of the component.
@@ -83,11 +83,11 @@ Use `NgStyle` to set multiple inline styles simultaneously, based on the state o
In the following example, `setCurrentStyles()` sets the property `currentStyles` with an object that defines three styles, based on the state of three other component properties.
-
+
1. To set the element's styles, add an `ngStyle` property binding to `currentStyles`.
-
+
For this use case, Angular applies the styles upon initialization and in case of changes.
To do this, the full example calls `setCurrentStyles()` initially with `ngOnInit()` and when the dependent properties change through a button click.
@@ -101,7 +101,7 @@ Use `` when there's no single element to host the directive.
Here's a conditional paragraph using ``.
-
+
@@ -111,7 +111,7 @@ Here's a conditional paragraph using ``.
1. To conditionally exclude an `