diff --git a/adev-ja/src/app/features/home/components/deferrable-views-example/deferrable-views-example.en.html b/adev-ja/src/app/features/home/components/deferrable-views-example/deferrable-views-example.en.html
new file mode 100644
index 0000000000..819ce423bb
--- /dev/null
+++ b/adev-ja/src/app/features/home/components/deferrable-views-example/deferrable-views-example.en.html
@@ -0,0 +1,38 @@
+
+
+
Deferrable Views
+
+ Deferrable views (also known as @defer blocks) reduce the initial bundle size
+ of your application by deferring the loading of code that is not strictly necessary for the
+ initial rendering of a page.
+
+
+
+
+
+
+
+
+ data-visualization-page.html
+
+
+
+
+
+
+
+
+ data-visualization-page.ts
+
+
+
+
+
+
+
diff --git a/adev-ja/src/app/features/home/components/deferrable-views-example/deferrable-views-example.html b/adev-ja/src/app/features/home/components/deferrable-views-example/deferrable-views-example.html
new file mode 100644
index 0000000000..8753b0d41b
--- /dev/null
+++ b/adev-ja/src/app/features/home/components/deferrable-views-example/deferrable-views-example.html
@@ -0,0 +1,37 @@
+
diff --git a/adev-ja/src/app/features/home/components/hydration-example/hydration-example.en.html b/adev-ja/src/app/features/home/components/hydration-example/hydration-example.en.html
new file mode 100644
index 0000000000..24af1eda1a
--- /dev/null
+++ b/adev-ja/src/app/features/home/components/hydration-example/hydration-example.en.html
@@ -0,0 +1,216 @@
+
Hydration
+
+ Hydration is the process that restores the server-side rendered application on the client
+
+
+ This demo showcases Angular's hydration strategies, allowing you to simulate network latency and
+ observe how different components hydrate based on their configured triggers.
+
diff --git a/adev-ja/src/app/features/home/components/signals-demo/signals-demo.en.html b/adev-ja/src/app/features/home/components/signals-demo/signals-demo.en.html
new file mode 100644
index 0000000000..19575c5c4d
--- /dev/null
+++ b/adev-ja/src/app/features/home/components/signals-demo/signals-demo.en.html
@@ -0,0 +1,51 @@
+
+
+
Signals: Fine-Grained Reactivity
+
+ Type in the search box to filter the list. A
+ computed signal automatically recalculates the
+ filteredItems whenever the searchTerm signal changes.
+
+
+
+
+
+ @for (item of filteredItems(); track item) {
+
{{ item }}
+ }
+
+
+
+
+
+
+
+
+
+ component.ts
+
+
+
+
+
+
+
+
+ component.html
+
+
+
+
+
+
diff --git a/adev-ja/src/app/features/home/components/signals-demo/signals-demo.html b/adev-ja/src/app/features/home/components/signals-demo/signals-demo.html
new file mode 100644
index 0000000000..7422c01a9a
--- /dev/null
+++ b/adev-ja/src/app/features/home/components/signals-demo/signals-demo.html
@@ -0,0 +1,51 @@
+
}
```
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 c8e929e383..1a9a8a6be5 100644
--- a/adev-ja/src/content/ai/mcp-server-setup.en.md
+++ b/adev-ja/src/content/ai/mcp-server-setup.en.md
@@ -22,10 +22,12 @@ Some tools are provided in experimental / preview status since they are new or n
| Name | Description | `local-only` | `read-only` |
| :------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :----------: | :---------: |
| `build` | Perform a one-off, non-watched build using `ng build`. | ✅ | ❌ |
-| `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](/reference/migrations) | ✅ | ❌ |
| `devserver.start` | Asynchronously starts a development server that watches the workspace for changes, similar to running `ng serve`. Since this is asynchronous it returns immediately. To manage the resulting server, use the `devserver.stop` and `devserver.wait_for_build` tools. | ✅ | ✅ |
| `devserver.stop` | Stops a development server started by `devserver.start`. | ✅ | ✅ |
| `devserver.wait_for_build` | Returns the output logs of the most recent build in a running development server started by `devserver.start`. If a build is currently ongoing, it will first wait for that build to complete and then return the logs. | ✅ | ✅ |
+| `e2e` | Executes the end-to-end tests configured in the project. | ✅ | ✅ |
+| `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) | ✅ | ❌ |
+| `test` | Runs the project's unit tests. | ✅ | ✅ |
## Get Started
@@ -133,11 +135,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` |
-| `--experimental-tool` `-E` | `string` | Enable an [experimental tool](#experimental-tools). Separate multiple options by spaces, e.g. `-E tool_a tool_b`. You can also enable tool groups like `devserver` to enable all related tools at once, e.g. `-E devserver`. | |
+| 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`. Enable all `devserver.x` tools by using `-E devserver`. | |
For example, to run the server in read-only mode in VS Code, you would update your `mcp.json` like this:
diff --git a/adev-ja/src/content/ai/mcp-server-setup.md b/adev-ja/src/content/ai/mcp-server-setup.md
index ec20c1d2e1..6eba92921a 100644
--- a/adev-ja/src/content/ai/mcp-server-setup.md
+++ b/adev-ja/src/content/ai/mcp-server-setup.md
@@ -22,10 +22,12 @@ Angular CLI MCPサーバーは、開発ワークフローを支援するいく
| 名前 | 説明 | `local-only` | `read-only` |
| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------: | :---------: |
| `build` | `ng build`を使用して、1回限りの非監視ビルドを実行します。 | ✅ | ❌ |
-| `modernize` | コード移行を実行し、最新のベストプラクティスと構文に合わせてAngularコードをモダナイズする方法についてさらなる指示を提供します。[詳細を見る](/reference/migrations) | ✅ | ❌ |
| `devserver.start` | ワークスペースの変更を監視する開発サーバーを非同期に起動します。`ng serve`の実行に似ています。これは非同期であるため、即座に戻ります。結果として得られるサーバーを管理するには、`devserver.stop`および`devserver.wait_for_build`ツールを使用します。 | ✅ | ✅ |
| `devserver.stop` | `devserver.start`によって起動された開発サーバーを停止します。 | ✅ | ✅ |
| `devserver.wait_for_build` | `devserver.start`によって起動された実行中の開発サーバーにおける最新のビルドの出力ログを返します。ビルドが現在進行中の場合、まずそのビルドが完了するのを待ってからログを返します。 | ✅ | ✅ |
+| `e2e` | プロジェクトで設定されたエンドツーエンドテストを実行します。 | ✅ | ✅ |
+| `modernize` | コード移行を実行し、最新のベストプラクティスと構文に合わせてAngularコードをモダナイズする方法についてさらなる指示を提供します。[詳細を見る](https://angular.dev/reference/migrations) | ✅ | ❌ |
+| `test` | プロジェクトのユニットテストを実行します。 | ✅ | ✅ |
## 開始方法 {#get-started}
@@ -137,7 +139,7 @@ MCPサーバーの設定に関する最新の手順については、JetBrains
| :---------------------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------- |
| `--read-only` | `boolean` | プロジェクトに変更を加えないツールのみを登録します。エディタまたはコーディングエージェントは引き続き編集を実行する場合があります。 | `false` |
| `--local-only` | `boolean` | インターネット接続を必要としないツールのみを登録します。エディタまたはコーディングエージェントは引き続きネットワーク経由でデータを送信する場合があります。 | `false` |
-| `--experimental-tool` `-E` | `string` | [実験的ツール](#experimental-tools)を有効にします。複数のオプションをスペースで区切ります。例: `-E tool_a tool_b`。`devserver`のようなツールグループを有効にして、関連するすべてのツールを一度に有効にすることもできます。例: `-E devserver`。 | |
+| `--experimental-tool` `-E` | `string` | [実験的ツール](#experimental-tools)を有効にします。複数のオプションをスペースで区切ります。例: `-E tool_a tool_b`。`-E devserver`を使用してすべての`devserver.x`ツールを有効にできます。 | |
たとえば、VS Codeにおいて読み取り専用モードでサーバーを実行する場合は、`mcp.json`を次のように更新します:
diff --git a/adev-ja/src/content/ai/overview.en.md b/adev-ja/src/content/ai/overview.en.md
index e2da24e392..b11f3e6623 100644
--- a/adev-ja/src/content/ai/overview.en.md
+++ b/adev-ja/src/content/ai/overview.en.md
@@ -38,7 +38,7 @@ 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.
-- [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/frameworks/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.
diff --git a/adev-ja/src/content/ai/overview.md b/adev-ja/src/content/ai/overview.md
index a8ed4a1fe1..a9d0604c72 100644
--- a/adev-ja/src/content/ai/overview.md
+++ b/adev-ja/src/content/ai/overview.md
@@ -38,7 +38,7 @@ GenkitとAngularで構築する方法の例を次に示します。
- [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/frameworks/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アプリケーションを構築し、ユーザーインタラクションに基づいてストーリーを動的に生成し、発生するイベントに付随する美しい画像パネルを特徴とする方法を学びます。より高度なユースケースを試したい場合は、ここから始めましょう。
diff --git a/adev-ja/src/content/best-practices/a11y.en.md b/adev-ja/src/content/best-practices/a11y.en.md
index 14e751f560..54994a5c19 100644
--- a/adev-ja/src/content/best-practices/a11y.en.md
+++ b/adev-ja/src/content/best-practices/a11y.en.md
@@ -37,13 +37,10 @@ Some ARIA patterns expose DOM APIs or directive inputs that accept structured va
Attention
Please review your answers before continuing.
-
+
-
-`,
+ `,
})
export class ReviewDialog {}
```
@@ -99,7 +96,7 @@ The following example shows how to make a progress bar accessible by using host
path="adev/src/content/examples/accessibility/src/app/progress-bar.component.ts"
language="ts"
linenums
- highlight="[12, 20]"/>
+ highlight="[12, 19]"/>
-
- Home
-
-
- About
-
-
- Shop
-
+ Home
+ About
+ Shop
```
diff --git a/adev-ja/src/content/best-practices/a11y.md b/adev-ja/src/content/best-practices/a11y.md
index 36bba194d0..7c94114817 100644
--- a/adev-ja/src/content/best-practices/a11y.md
+++ b/adev-ja/src/content/best-practices/a11y.md
@@ -37,13 +37,10 @@ HELPFUL: 慣習的に、HTML属性は小文字の名前を使用します (`tabi
Attention
Please review your answers before continuing.
-
+
-
-`,
+ `,
})
export class ReviewDialog {}
```
@@ -99,7 +96,7 @@ Angularコンポーネントを作成する際には、サポートされてい
path="adev/src/content/examples/accessibility/src/app/progress-bar.component.ts"
language="ts"
linenums
- highlight="[12, 20]"/>
+ highlight="[12, 19]"/>
e instanceof NavigationEnd)).subscribe(() => {
```angular-html
```
diff --git a/adev-ja/src/content/best-practices/error-handling.en.md b/adev-ja/src/content/best-practices/error-handling.en.md
index d9cb07d367..8f88da54dd 100644
--- a/adev-ja/src/content/best-practices/error-handling.en.md
+++ b/adev-ja/src/content/best-practices/error-handling.en.md
@@ -52,7 +52,7 @@ Errors that are caught neither by the application code nor by the framework's ap
### Client-side rendering
-Adding [`provideBrowserGlobalErrorListeners()`](/api/core/provideBrowserGlobalErrorListeners) to the [ApplicationConfig](guide/di/dependency-injection#at-the-application-root-level-using-applicationconfig) adds the `'error'` and `'unhandledrejection'` listeners to the browser window and forwards those errors to `ErrorHandler`. The Angular CLI generates new applications with this provider by default. The Angular team recommends handling these global errors for most applications, either with the framework's built-in listeners or with your own custom listeners. If you provide custom listeners, you can remove `provideBrowserGlobalErrorListeners`.
+Adding [`provideBrowserGlobalErrorListeners()`](/api/core/provideBrowserGlobalErrorListeners) to the [ApplicationConfig](guide/di/defining-dependency-providers#application-bootstrap) adds the `'error'` and `'unhandledrejection'` listeners to the browser window and forwards those errors to `ErrorHandler`. The Angular CLI generates new applications with this provider by default. The Angular team recommends handling these global errors for most applications, either with the framework's built-in listeners or with your own custom listeners. If you provide custom listeners, you can remove `provideBrowserGlobalErrorListeners`.
### Server-side and hybrid rendering
diff --git a/adev-ja/src/content/best-practices/error-handling.md b/adev-ja/src/content/best-practices/error-handling.md
index 94e84906f9..3fc3e38128 100644
--- a/adev-ja/src/content/best-practices/error-handling.md
+++ b/adev-ja/src/content/best-practices/error-handling.md
@@ -52,7 +52,7 @@ export class GlobalErrorHandler implements ErrorHandler {
### クライアントサイドレンダリング {#client-side-rendering}
-[ApplicationConfig](guide/di/dependency-injection#at-the-application-root-level-using-applicationconfig)に[`provideBrowserGlobalErrorListeners()`](/api/core/provideBrowserGlobalErrorListeners)を追加すると、ブラウザウィンドウに`'error'`と`'unhandledrejection'`リスナーが追加され、それらのエラーが`ErrorHandler`に転送されます。Angular CLIは、デフォルトでこのプロバイダーを使用して新しいアプリケーションを生成します。Angularチームは、ほとんどのアプリケーションで、フレームワークの組み込みリスナーまたは独自のカスタムリスナーのいずれかを使用して、これらのグローバルエラーを処理することを推奨しています。カスタムリスナーを提供する場合は、`provideBrowserGlobalErrorListeners`を削除できます。
+[ApplicationConfig](guide/di/defining-dependency-providers#application-bootstrap)に[`provideBrowserGlobalErrorListeners()`](/api/core/provideBrowserGlobalErrorListeners)を追加すると、ブラウザウィンドウに`'error'`と`'unhandledrejection'`リスナーが追加され、それらのエラーが`ErrorHandler`に転送されます。Angular CLIは、デフォルトでこのプロバイダーを使用して新しいアプリケーションを生成します。Angularチームは、ほとんどのアプリケーションで、フレームワークの組み込みリスナーまたは独自のカスタムリスナーのいずれかを使用して、これらのグローバルエラーを処理することを推奨しています。カスタムリスナーを提供する場合は、`provideBrowserGlobalErrorListeners`を削除できます。
### サーバーサイドおよびハイブリッドレンダリング {#server-side-and-hybrid-rendering}
diff --git a/adev-ja/src/content/best-practices/performance/overview.md b/adev-ja/src/content/best-practices/performance/overview.md
new file mode 100644
index 0000000000..3ff3ac8044
--- /dev/null
+++ b/adev-ja/src/content/best-practices/performance/overview.md
@@ -0,0 +1,43 @@
+# Performance
+
+Angular includes many optimizations out of the box, but as applications grow, you may need to fine-tune both how quickly your app loads and how responsive it feels during use. These guides cover the tools and techniques Angular provides to help you build fast applications.
+
+## Loading performance
+
+Loading performance determines how quickly your application becomes visible and interactive. Slow loading directly impacts [Core Web Vitals](https://web.dev/vitals/) like Largest Contentful Paint (LCP) and Time to First Byte (TTFB).
+
+| Technique | What it does | When to use it |
+| :------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------- |
+| [Lazy-loaded routes](guide/routing/define-routes#lazily-loaded-components-and-routes) | Defers loading route components until navigation, reducing the initial bundle size | Applications with multiple routes where not all are needed on initial load |
+| [Deferred loading with `@defer`](best-practices/performance/defer) | Splits components into separate bundles that load on demand | Components not visible on initial render, heavy third-party libraries, below-the-fold content |
+| [Image optimization](best-practices/performance/image-optimization) | Prioritizes LCP images, lazy loads others, generates responsive `srcset` attributes | Any application that displays images |
+| [Server-side rendering](best-practices/performance/ssr) | Renders pages on the server for faster first paint and better SEO, with [hydration](guide/hydration) to restore interactivity and [incremental hydration](guide/incremental-hydration) to defer hydrating sections until needed | Content-heavy applications, pages that need search engine indexing |
+
+## Runtime performance
+
+Runtime performance determines how responsive your application feels after it loads. Angular's change detection system keeps the DOM in sync with your data, and optimizing how and when it runs is the primary lever for improving runtime performance.
+
+| Technique | What it does | When to use it |
+| :-------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------ |
+| [Zoneless change detection](guide/zoneless) | Removes ZoneJS overhead and triggers change detection only when signals or events indicate a change | New applications (default in Angular v21+), or existing applications ready to migrate |
+| [Slow computations](best-practices/slow-computations) | Identifies and optimizes expensive template expressions and lifecycle hooks | Profiling reveals specific components causing slow change detection cycles |
+| [Skipping component subtrees](best-practices/skipping-subtrees) | Uses `OnPush` change detection to skip unchanged component trees | Applications that need finer control over change detection |
+| [Zone pollution](best-practices/zone-pollution) | Prevents unnecessary change detection caused by third-party libraries or timers | Zone-based applications where profiling reveals excessive change detection cycles |
+
+## Measuring performance
+
+Identifying what to optimize is just as important as knowing how to optimize it. Angular integrates with browser developer tools to help you find bottlenecks.
+
+| Tool | What it does |
+| :------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [Chrome DevTools profiling](best-practices/profiling-with-chrome-devtools) | Records Angular-specific performance data alongside browser profiling, with color-coded flame charts that show component rendering, change detection cycles, and lifecycle hooks |
+| [Angular DevTools](tools/devtools) | A browser extension that provides a component tree inspector and a profiler for visualizing change detection cycles |
+
+## What to optimize first
+
+If you are unsure where to start, profile your application first using the [Chrome DevTools Angular track](best-practices/profiling-with-chrome-devtools) to identify specific bottlenecks.
+
+As a general starting point:
+
+- **Slow initial load** — Use [`@defer`](best-practices/performance/defer) to split large components out of the main bundle, [`NgOptimizedImage`](best-practices/performance/image-optimization) to prioritize above-the-fold images, and [server-side rendering](best-practices/performance/ssr) to deliver content faster.
+- **Slow interactions after load** — Check whether [zoneless change detection](guide/zoneless) is enabled, look for [slow computations](best-practices/slow-computations) in templates or lifecycle hooks, and consider [`OnPush`](best-practices/skipping-subtrees) to reduce unnecessary change detection.
diff --git a/adev-ja/src/content/best-practices/runtime-performance/profiling-with-chrome-devtools.md b/adev-ja/src/content/best-practices/runtime-performance/profiling-with-chrome-devtools.md
index 67a98b65e0..d992e529a6 100644
--- a/adev-ja/src/content/best-practices/runtime-performance/profiling-with-chrome-devtools.md
+++ b/adev-ja/src/content/best-practices/runtime-performance/profiling-with-chrome-devtools.md
@@ -25,11 +25,10 @@ You can use the Angular track to better understand how your code runs in the bro
You can enable Angular profiling in one of two ways:
-1. Run `ng.enableProfiling()` in Chrome's console panel, or
-1. Include a call to `enableProfiling()` in your application startup code (imported from `@angular/core`).
+1. Run [`ng.enableProfiling()`](api/core/enableProfiling) in Chrome's console panel, or
+1. Include a call to [`enableProfiling()`](api/core/enableProfiling) in your application startup code (imported from `@angular/core`).
-NOTE:
-Angular profiling works exclusively in development mode.
+NOTE: Angular profiling works exclusively in development mode.
Here is an example of how you can enable the integration in the application bootstrap to capture all possible events:
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 77167acbed..2f549e4185 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
@@ -6,7 +6,7 @@ JavaScriptは、デフォルトでは、複数の異なるコンポーネント
アプリケーションの一部が状態変化の影響を受けないと確信できる場合は、[OnPush](/api/core/ChangeDetectionStrategy)を使用して、コンポーネントのサブツリー全体の変更検知をスキップできます。
-## `OnPush`の使用
+## `OnPush`の使用 {#using-onpush}
OnPush変更検知は、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 744080ee3d..b135069985 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
@@ -19,7 +19,7 @@ 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.
+- **Caching using pure pipes**. You can move the heavy computation to a pure [pipe](guide/templates/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.
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 6b32e76466..9a8c542f75 100644
--- a/adev-ja/src/content/best-practices/style-guide.en.md
+++ b/adev-ja/src/content/best-practices/style-guide.en.md
@@ -197,7 +197,7 @@ ensures that the value set by Angular is not overwritten.
```ts
@Component({
- /* ... */
+ /*...*/
})
export class UserProfile {
readonly userId = input();
@@ -211,7 +211,7 @@ advice applies to output properties and queries, but not input properties.
```ts
@Component({
- /* ... */
+ /*...*/
})
export class UserProfile {
@Output() readonly userSaved = new EventEmitter();
@@ -276,7 +276,7 @@ then delegate to more specific behaviors based on the event details:
```ts
@Component({
- /* ... */
+ /*...*/
})
class RichText {
handleKeydown(event: KeyboardEvent) {
@@ -323,7 +323,7 @@ your class, import and `implement` these interfaces to ensure that the methods a
import {Component, OnInit} from '@angular/core';
@Component({
- /* ... */
+ /*...*/
})
export class UserProfile implements OnInit {
// The `OnInit` interface ensures this method is named correctly.
diff --git a/adev-ja/src/content/best-practices/style-guide.md b/adev-ja/src/content/best-practices/style-guide.md
index fc541f67c0..3e2bce8a0d 100644
--- a/adev-ja/src/content/best-practices/style-guide.md
+++ b/adev-ja/src/content/best-practices/style-guide.md
@@ -197,7 +197,7 @@ readonlyアクセス修飾子は、Angularによって設定された値が上
```ts
@Component({
- /* ... */
+ /*...*/
})
export class UserProfile {
readonly userId = input();
@@ -211,7 +211,7 @@ export class UserProfile {
```ts
@Component({
- /* ... */
+ /*...*/
})
export class UserProfile {
@Output() readonly userSaved = new EventEmitter();
@@ -276,7 +276,7 @@ export class UserProfile {
```ts
@Component({
- /* ... */
+ /*...*/
})
class RichText {
handleKeydown(event: KeyboardEvent) {
@@ -323,7 +323,7 @@ Angularは、各ライフサイクルメソッドに対応するTypeScriptイン
import {Component, OnInit} from '@angular/core';
@Component({
- /* ... */
+ /*...*/
})
export class UserProfile implements OnInit {
// The `OnInit` interface ensures this method is named correctly.
diff --git a/adev-ja/src/content/best-practices/update.en.md b/adev-ja/src/content/best-practices/update.en.md
index 57297149e8..0e2cabdfa1 100644
--- a/adev-ja/src/content/best-practices/update.en.md
+++ b/adev-ja/src/content/best-practices/update.en.md
@@ -43,7 +43,7 @@ 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#angular-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
diff --git a/adev-ja/src/content/best-practices/update.md b/adev-ja/src/content/best-practices/update.md
index 0c2aba53c6..b4b7735662 100644
--- a/adev-ja/src/content/best-practices/update.md
+++ b/adev-ja/src/content/best-practices/update.md
@@ -43,7 +43,7 @@ Angularアップデートガイドは、指定した現在のバージョンと
簡単なアップデートの場合は、CLIコマンド [`ng update`](cli/update) で十分です。
追加の引数なしで、[`ng update`](cli/update)は、使用可能なアップデートをリストし、アプリケーションを最新バージョンにアップデートするための推奨される手順を提供します。
-[Angularのバージョン管理とリリース](reference/releases#versioning 'Angular リリースプラクティス、バージョン管理')では、リリースのバージョン番号に基づいて期待できる変更レベルについて説明しています。
+[Angularのバージョン管理とリリース](reference/releases#angular-versioning 'Angular リリースプラクティス、バージョン管理')では、リリースのバージョン番号に基づいて期待できる変更レベルについて説明しています。
また、サポートされているアップデートパスについても説明しています。
## リソースの概要
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 ee763e37af..9b28a809a4 100644
--- a/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md
+++ b/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md
@@ -7,10 +7,10 @@ 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.
```angular-ts
-import { Component } from '@angular/core';
-import { AsyncPipe } from '@angular/common';
-import { interval } from 'rxjs';
-import { toSignal } from '@angular/core/rxjs-interop';
+import {Component} from '@angular/core';
+import {AsyncPipe} from '@angular/common';
+import {interval} from 'rxjs';
+import {toSignal} from '@angular/core/rxjs-interop';
@Component({
template: `{{ counter() }}`,
@@ -47,7 +47,7 @@ If you don't provide an `initialValue`, the resulting signal will return `undefi
Some Observables are guaranteed to emit synchronously, such as `BehaviorSubject`. In those cases, you can specify the `requireSync: true` option.
-When `requiredSync` is `true`, `toSignal` enforces that the Observable emits synchronously on subscription. This guarantees that the signal always has a value, and no `undefined` type or initial value is required.
+When `requireSync` is `true`, `toSignal` enforces that the Observable emits synchronously on subscription. This guarantees that the signal always has a value, and no `undefined` type or initial value is required.
### `manualCleanup`
diff --git a/adev-ja/src/content/guide/animations/complex-sequences.en.md b/adev-ja/src/content/guide/animations/complex-sequences.en.md
index ddd3fe3899..4070303cee 100644
--- a/adev-ja/src/content/guide/animations/complex-sequences.en.md
+++ b/adev-ja/src/content/guide/animations/complex-sequences.en.md
@@ -1,6 +1,6 @@
# Complex animation sequences
-IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations/enter-and-leave). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps.
+IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](/guide/animations). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps.
So far, we've learned simple animations of single HTML elements.
Angular also lets you animate coordinated sequences, such as an entire grid or list of elements as they enter and leave a page.
@@ -54,7 +54,7 @@ The following example demonstrates how to use the `query()` and `stagger()` func
- 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
@@ -67,7 +67,7 @@ HELPFUL: The [`group()`](api/animations/group) function is used to group animati
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
@@ -91,11 +91,11 @@ 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:
diff --git a/adev-ja/src/content/guide/animations/complex-sequences.md b/adev-ja/src/content/guide/animations/complex-sequences.md
index bff306decc..f68ddbd372 100644
--- a/adev-ja/src/content/guide/animations/complex-sequences.md
+++ b/adev-ja/src/content/guide/animations/complex-sequences.md
@@ -1,6 +1,6 @@
# 複雑なアニメーションシーケンス
-IMPORTANT: `@angular/animations`パッケージは現在非推奨です。Angularチームは、新しく書くコードのアニメーションには`animate.enter`と`animate.leave`を使ったネイティブCSSの利用を推奨します。詳しくは、新しいenterとleaveの[アニメーションガイド](guide/animations/enter-and-leave)を参照してください。また、アプリケーションで純粋なCSSアニメーションへの移行を始める方法については、[AngularのAnimationsパッケージからの移行](guide/animations/migration)も参照してください。
+IMPORTANT: `@angular/animations`パッケージは現在非推奨です。Angularチームは、新しく書くコードのアニメーションには`animate.enter`と`animate.leave`を使ったネイティブCSSの利用を推奨します。詳しくは、新しいenterとleaveの[アニメーションガイド](/guide/animations)を参照してください。また、アプリケーションで純粋なCSSアニメーションへの移行を始める方法については、[AngularのAnimationsパッケージからの移行](guide/animations/migration)も参照してください。
ここまで、単一のHTML要素のシンプルなアニメーションを学んできました。
Angularでは、ページに出入りする要素のグリッド全体やリスト全体など、連携したシーケンスもアニメーション化できます。
@@ -54,7 +54,7 @@ Angularでは、ページに出入りする要素のグリッド全体やリス
- `stagger()` を使って各アニメーションを30ミリ秒ずつ遅らせます。
- カスタム定義のイージングカーブを使って各要素を0.5秒かけてアニメーションし、フェードインと`transform`の解除を同時に行います。
-
+
## group() 関数を使った並行アニメーション {#parallel-animation-using-group-function}
@@ -67,7 +67,7 @@ HELPFUL: [`group()`](api/animations/group) 関数は、アニメーション化
次の例は、`:enter` と `:leave` の両方で [`group()`](api/animations/group) を使用し、2つの異なるタイミング設定を適用します。これにより、同じ要素に2つの独立したアニメーションを並行して適用できます。
-
+
## 順次アニメーションと並行アニメーション {#sequential-vs-parallel-animations}
@@ -91,11 +91,11 @@ Filter/Staggerタブで、**Search Heroes** テキストボックスに `Magnet`
HTMLテンプレートには `filterAnimation` というトリガーが含まれます。
-
+
コンポーネントのデコレーターにある `filterAnimation` には3つのトランジションが含まれます。
-
+
この例のコードは次のタスクを実行します:
diff --git a/adev-ja/src/content/guide/animations/css.en.md b/adev-ja/src/content/guide/animations/css.en.md
index a88a32ef70..8d08ff0e58 100644
--- a/adev-ja/src/content/guide/animations/css.en.md
+++ b/adev-ja/src/content/guide/animations/css.en.md
@@ -52,10 +52,10 @@ Similarly, you can use `transition-duration`, `transition-delay`, and `transitio
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
@@ -64,10 +64,10 @@ 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.
@@ -76,18 +76,18 @@ 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).
@@ -96,10 +96,10 @@ 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
@@ -147,10 +147,10 @@ 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
@@ -171,10 +171,10 @@ In this example, the `rotate` and `fade-in` animations fire at the same time, bu
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/css.md b/adev-ja/src/content/guide/animations/css.md
index 517a78f6f8..9c991483cb 100644
--- a/adev-ja/src/content/guide/animations/css.md
+++ b/adev-ja/src/content/guide/animations/css.md
@@ -52,10 +52,10 @@ CSSには、アプリケーション内で美しく魅力的なアニメーシ
アニメーションは、CSSのスタイルやクラスを切り替えることでトリガーできます。クラスが要素に追加されるとアニメーションが実行され、クラスを削除すると、その要素に定義されているCSSに戻ります。例を示します。
-
-
-
-
+
+
+
+
## トランジションとトリガー {#transition-and-triggers}
@@ -64,10 +64,10 @@ CSSには、アプリケーション内で美しく魅力的なアニメーシ
CSS Gridを使用すると、`height: auto`へのアニメーションを実現できます。
-
-
-
-
+
+
+
+
すべてのブラウザをサポートする必要がない場合は、`height: auto`をアニメーション化するためのより本質的な解決策である`calc-size()`も確認してください。詳しくは、[MDNのドキュメント](https://developer.mozilla.org/en-US/docs/Web/CSS/calc-size)とこの項目に関連する[チュートリアル](https://frontendmasters.com/blog/one-of-the-boss-battles-of-css-is-almost-won-transitioning-to-auto/)を参照してください。
@@ -76,30 +76,30 @@ CSS Gridを使用すると、`height: auto`へのアニメーションを実現
要素がビューに入るとき、またはビューから出るときのアニメーションを作成できます。まずは、ビューに入るときのアニメーションを見ていきましょう。`animate.enter`を使うと、要素がビューに入るときにアニメーション用のクラスが適用されます。
-
-
-
-
+
+
+
+
ビューから出るときのアニメーションも、ビューに入るときと同様です。`animate.leave`で、要素がビューから出るときに適用するCSSクラスを指定します。
-
-
-
-
+
+
+
+
-`animate.enter`と`animate.leave`について詳しくは、[EnterとLeaveのアニメーションガイド](guide/animations/enter-and-leave)を参照してください。
+`animate.enter`と`animate.leave`について詳しくは、[EnterとLeaveのアニメーションガイド](guide/animations)を参照してください。
### インクリメントとデクリメントをアニメーション化する {#animating-increment-and-decrement}
インクリメントとデクリメントに合わせてアニメーションするのは、アプリケーションでよくあるパターンです。以下はその例です。
-
-
-
-
+
+
+
+
### アニメーション(またはすべてのアニメーション)を無効にする {#disabling-an-animation-or-all-animations}
@@ -147,10 +147,10 @@ NOTE: これらのコールバックはバブリング(イベント伝播)
よくある効果の1つに、リスト内の各要素のアニメーションを段階的に遅らせてカスケード効果を作るものがあります。これは`animation-delay`または`transition-delay`を利用して実現できます。次はそのCSSの例です。
-
-
-
-
+
+
+
+
### 並行アニメーション {#parallel-animations}
@@ -171,10 +171,10 @@ NOTE: これらのコールバックはバブリング(イベント伝播)
`@for`ループ内の要素は削除されて再追加されるため、enterアニメーションとして`@starting-styles`を使用したアニメーションが実行されます。同じ挙動は`animate.enter`でも実現できます。要素が削除されるときにアニメーションするには、以下の例のように`animate.leave`を使用します。
-
-
-
-
+
+
+
+
## アニメーションをプログラムで制御する {#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 2a994183a9..73be130a0f 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
@@ -45,7 +45,7 @@ You can use `animate.leave` to animate elements as they _leave_ the DOM. You can
When the animation completes, Angular automatically removes the animated element from the DOM.
-NOTE: When using multiple keyframe animations or transition properties on a an element, Angular waits to remove the element only _after_ the longest of those animations has completed.
+NOTE: When using multiple keyframe animations or transition properties on an element, Angular waits to remove the element only _after_ the longest of those animations has completed.
`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.
@@ -55,6 +55,16 @@ NOTE: When using multiple keyframe animations or transition properties on a an e
+### Element removal order matters
+
+There is some nuance to how `animate.leave` animations are run and when an animation will occur. `animate.leave` works if it is placed on the element that is being removed. However, `animate.leave` will **not** animate if it is on an element that is a _descendent_ of the element being removed. This is because when a parent node is removed, it takes the entire sub tree with it, and since there are no animations on that parent node, it will be removed immediately. This means there's no element to animate away with `animate.leave`. You will need to consider this in your usage of `animate.leave`.
+
+
+
+
+
+
+
## Event Bindings, Functions, and Third-party Libraries
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.
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 243f06d667..8191fb9722 100644
--- a/adev-ja/src/content/guide/animations/enter-and-leave.md
+++ b/adev-ja/src/content/guide/animations/enter-and-leave.md
@@ -55,6 +55,16 @@ NOTE: 要素に複数のキーフレームアニメーションまたはtransiti
+### 要素の削除順序が重要 {#element-removal-order-matters}
+
+`animate.leave`アニメーションの実行方法とアニメーションが発生するタイミングには、いくつかの微妙な点があります。`animate.leave`は、削除される要素に配置されている場合に機能します。ただし、`animate.leave`は、削除される要素の_子孫_の要素にある場合はアニメーション**しません**。これは、親ノードが削除されると、サブツリー全体が一緒に削除され、その親ノードにアニメーションがないため、即座に削除されるためです。これは、`animate.leave`でアニメーション化する要素がないことを意味します。`animate.leave`の使用においてこのことを考慮する必要があります。
+
+
+
+
+
+
+
## イベントバインディング、関数、およびサードパーティライブラリ {#event-bindings-functions-and-third-party-libraries}
`animate.enter`と`animate.leave`はどちらも、関数呼び出しを可能にするイベントバインディング構文をサポートしています。この構文を使用して、コンポーネントコード内の関数を呼び出したり、[GSAP](https://gsap.com/)、[anime.js](https://animejs.com/)などのサードパーティのアニメーションライブラリ、またはその他のJavaScriptアニメーションライブラリを利用したり可能です。
diff --git a/adev-ja/src/content/guide/animations/migration.md b/adev-ja/src/content/guide/animations/migration.md
index 7872a9b507..e3a3e8dff3 100644
--- a/adev-ja/src/content/guide/animations/migration.md
+++ b/adev-ja/src/content/guide/animations/migration.md
@@ -38,7 +38,7 @@ The animations package allowed you to define various states using the [`state()`
#### With Animations Package
-
+
This same behavior can be accomplished natively by using CSS classes either using a keyframe animation or transition styling.
@@ -69,17 +69,17 @@ The animations package required specifying triggers using the `trigger()` functi
#### With Animations Package
-
-
-
+
+
+
#### With Native CSS
-
-
-
-
+
+
+
+
## Transition and Triggers
@@ -97,19 +97,19 @@ The animations package offers the ability to animate things that have been histo
#### 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.
@@ -121,29 +121,25 @@ The animations package offered the previously mentioned pattern matching for ent
#### 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).
@@ -155,17 +151,17 @@ Along with the aforementioned `:enter` and `:leave`, there's also `:increment` a
#### With Animations Package
-
-
-
+
+
+
#### With Native CSS
-
-
-
-
+
+
+
+
### Parent / Child Animations
@@ -226,17 +222,17 @@ The `stagger()` function allowed you to delay the animation of each item in a li
#### With Animations Package
-
-
-
+
+
+
#### With Native CSS
-
-
-
-
+
+
+
+
### Parallel Animations
@@ -257,20 +253,20 @@ 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 Animations Package
-
-
-
+
+
+
#### With Native CSS
-
-
-
-
+
+
+
+
## Migrating usages of AnimationPlayer
diff --git a/adev-ja/src/content/guide/animations/overview.md b/adev-ja/src/content/guide/animations/overview.md
index 04981eaa65..ec2ee0d7c0 100644
--- a/adev-ja/src/content/guide/animations/overview.md
+++ b/adev-ja/src/content/guide/animations/overview.md
@@ -1,6 +1,6 @@
# Introduction to Angular animations
-IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations/enter-and-leave). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps.
+IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps.
Animation provides the illusion of motion: HTML elements change styling over time.
Well-designed animations can make your application more fun and straightforward to use, but they aren't just cosmetic.
@@ -52,7 +52,7 @@ For `NgModule` based applications import `BrowserAnimationsModule`, which introd
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.
@@ -61,7 +61,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.
-
+
@@ -84,7 +84,7 @@ Run the following command in terminal to generate the component:
ng g component open-close
```
-This will create the component at `src/app/open-close.component.ts`.
+This will create the component at `src/app/open-close.ts`.
### Animation state and styles
@@ -99,11 +99,11 @@ Let's see how Angular's [`state()`](api/animations/state) function works with th
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
@@ -171,7 +171,7 @@ HELPFUL: See the Material Design website's topic on [Natural easing curves](http
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.
@@ -179,7 +179,7 @@ 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.
@@ -212,7 +212,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.
@@ -225,7 +225,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.
@@ -242,9 +242,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
diff --git a/adev-ja/src/content/guide/animations/reusable-animations.md b/adev-ja/src/content/guide/animations/reusable-animations.md
index 350aaa4b4a..b1519edfe8 100644
--- a/adev-ja/src/content/guide/animations/reusable-animations.md
+++ b/adev-ja/src/content/guide/animations/reusable-animations.md
@@ -1,6 +1,6 @@
# Reusable animations
-IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations/enter-and-leave). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps.
+IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps.
This topic provides some examples of how to create reusable animations.
@@ -23,7 +23,7 @@ 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/route-animations.md b/adev-ja/src/content/guide/animations/route-animations.md
deleted file mode 100644
index 1fbbd973d0..0000000000
--- a/adev-ja/src/content/guide/animations/route-animations.md
+++ /dev/null
@@ -1,157 +0,0 @@
-# Route transition animations
-
-When a user navigates from one route to another, the Angular Router maps the URL path to the relevant component and displays its view. Animating this route transition can greatly enhance the user experience. The Router has support for the View Transitions API when navigating between routes in Chrome/Chromium browsers.
-
-HELPFUL: The Router's native View Transitions integration is currently in [developer preview](/reference/releases#developer-preview). Native View Transitions are also a relatively new feature so there may be limited support in some browsers.
-
-## How View Transitions work
-
-The native browser method that’s used for view transitions is `document.startViewTransition`. When `startViewTransition()` is called, the browser captures the current state of the page which includes taking a screenshot. The method takes a callback that updates the DOM and this function can be asynchronous. The new state is captured and the transition begins in the next animation frame when the promise returned by the callback resolves.
-
-Here’s an example of the startViewTransition api:
-
-```ts
-document.startViewTransition(async () => {
- await updateTheDOMSomehow();
-});
-```
-
-If you’re curious to read more about the details of the browser API, the [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions) is an invaluable resource.
-
-## How the Router uses view transitions
-
-Several things happen after navigation starts in the router: route matching, loading lazy routes and components, executing guards and resolvers to name a few. Once these have completed successfully, the new routes are ready to be activated. This route activation is the DOM update that we want to perform as part of the view transition.
-
-When the view transition feature is enabled, navigation “pauses” and a call is made to the browser’s `startViewTransition` method. Once the `startViewTransition` callback executes (this happens asynchronously, as outlined in the spec here), navigation “resumes”. The remaining steps for the router navigation include updating the browser URL and activating or deactivating the matched routes (the DOM update).
-
-Finally, the callback passed to `startViewTransition` returns a Promise that resolves once Angular has finished rendering. As described above, this indicates to the browser that the new DOM state should be captured and the transition should begin.
-
-View transitions are a [progressive enhancement](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement). If the browser does not support the API, the Router will perform the DOM updates without calling `startViewTransition` and the navigation will not be animated.
-
-## Enabling View Transitions in the Router
-
-To enable this feature, simply add `withViewTransitions` to the `provideRouter` or set `enableViewTransitions: true` in `RouterModule.forRoot`:
-
-```ts
-// Standalone bootstrap
-bootstrapApplication(MyApp, {providers: [
- provideRouter(ROUTES, withViewTransitions()),
-]});
-
-// NgModule bootstrap
-@NgModule({
- imports: [RouterModule.forRoot(routes, {enableViewTransitions: true})]
-})
-export class AppRouting {}
-```
-
-[Try the “count” example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-2dnvtm?file=src%2Fmain.ts)
-
-This example uses the counter application from the Chrome explainer and replaces the direct call to startViewTransition when the counter increments with a router navigation.
-
-## Using CSS to customize transitions
-
-View transitions can be customized with CSS. We can also instruct the browser to create separate elements for the transition by setting a view-transition-name. We can expand the first example by adding view-transition-name: count to the .count style in the Counter component. Then, in the global styles, we can define a custom animation for this view transition:
-
-```css
-/* Custom transition */
-@keyframes rotate-out {
- to {
- transform: rotate(90deg);
- }
-}
-@keyframes rotate-in {
- from {
- transform: rotate(-90deg);
- }
-}
-::view-transition-old(count),
-::view-transition-new(count) {
- animation-duration: 200ms;
- animation-name: -ua-view-transition-fade-in, rotate-in;
-}
-::view-transition-old(count) {
- animation-name: -ua-view-transition-fade-out, rotate-out;
-}
-```
-
-It is important that the view transition animations are defined in a global style file. They cannot be defined in the component styles because the default view encapsulation will scope the styles to the component.
-
-[Try the updated “count” example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-fwn4i7?file=src%2Fmain.ts)
-
-## Controlling transitions with onViewTransitionCreated
-
-The `withViewTransitions` router feature can also be called with an options object that includes an `onViewTransitionCreated` callback. This callback is run in an [injection context](/guide/di/dependency-injection-context#run-within-an-injection-context) and receives a [ViewTransitionInfo](/api/router/ViewTransitionInfo) object that includes the `ViewTransition` returned from `startViewTransition`, as well as the `ActivatedRouteSnapshot` that the navigation is transitioning from and the new one that it is transitioning to.
-
-This callback can be used for any number of customizations. For example, you might want to skip transitions under certain conditions. We use this on the new angular.dev docs site:
-
-```ts
-withViewTransitions({
- onViewTransitionCreated: ({transition}) => {
- const router = inject(Router);
- const targetUrl = router.getCurrentNavigation()!.finalUrl!;
- // Skip the transition if the only thing
- // changing is the fragment and queryParams
- const config = {
- paths: 'exact',
- matrixParams: 'exact',
- fragment: 'ignored',
- queryParams: 'ignored',
- };
-
- if (router.isActive(targetUrl, config)) {
- transition.skipTransition();
- }
- },
-}),
-```
-
-In this code snippet, we create a `UrlTree` from the `ActivatedRouteSnapshot` the navigation is going to. We then check with the Router to see if this `UrlTree` is already active, ignoring any differences in the fragment or query parameters. If it is already active, we call skipTransition which will skip the animation portion of the view transition. This is the case when clicking on an anchor link that will only scroll to another location in the same document.
-
-## Examples from the Chrome explainer adapted to Angular
-
-We’ve recreated some of the great examples from the Chrome Team in Angular for you to explore.
-
-### Transitioning elements don’t need to be the same DOM element
-
-* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#transitioning_elements_dont_need_to_be_the_same_dom_element)
-* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-dh8npr?file=src%2Fmain.ts)
-
-### Custom entry and exit animations
-
-* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#custom_entry_and_exit_transitions)
-* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-8kly3o)
-
-### Async DOM updates and waiting for content
-
-* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#async_dom_updates_and_waiting_for_content)
-
-> During this time, the page is frozen, so delays here should be kept to a minimum…in some cases it’s better to avoid the delay altogether, and use the content you already have.
-
-The view transition feature in the Angular router does not provide a way to delay the animation. For the moment, our stance is that it’s always better to use the content you have rather than making the page non-interactive for any additional amount of time.
-
-### Handle multiple view transition styles with view transition types
-
-* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#view-transition-types)
-* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-vxzcam)
-
-### Handle multiple view transition styles with a class name on the view transition root (deprecated)
-
-* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#changing-on-navigation-type)
-* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-nmnzzg?file=src%2Fmain.ts)
-
-### Transitioning without freezing other animations
-
-* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#transitioning-without-freezing)
-* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-76kgww)
-
-### Animating with Javascript
-
-* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#animating-with-javascript)
-* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-cklnkm)
-
-## Native View Transitions Alternative
-
-Animating the transition between routes can also be done with the `@angular/animations` package.
-The animation [triggers and transitions](/guide/animations/transition-and-triggers)
-can be derived from the router state, such as the current URL or `ActivatedRoute`.
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 1856a2e249..1e03b72ed9 100644
--- a/adev-ja/src/content/guide/animations/transition-and-triggers.md
+++ b/adev-ja/src/content/guide/animations/transition-and-triggers.md
@@ -1,6 +1,6 @@
# Animation transitions and triggers
-IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations/enter-and-leave). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps.
+IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps.
This guide goes into depth on special transition states such as the `*` wildcard and `void`. It shows how these special states are used for elements entering and leaving a view.
This section also explores multiple animation triggers, animation callbacks, and sequence-based animation using keyframes.
@@ -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.
@@ -52,7 +52,7 @@ To do this, list the more specific transitions _before_ `* => *`.
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
@@ -76,7 +76,7 @@ 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
-
+
In the preceding code, you applied the `void` state when the HTML element isn't attached to a view.
@@ -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.
@@ -177,7 +177,7 @@ Those elements can still animate.
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.
@@ -186,12 +186,12 @@ HELPFUL: Disabling animations application-wide is useful during end-to-end \(E2E
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.
@@ -204,7 +204,7 @@ An animation can influence an end user to _perceive_ the operation as faster, ev
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
@@ -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.
@@ -250,7 +250,7 @@ Here's an example of using keyframes to create a pulse effect:
The code snippet for this animation might look like this.
-
+
### Animatable properties and units
@@ -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.en.md b/adev-ja/src/content/guide/aria/accordion.en.md
index 2588aeeb47..4a27dc5e0b 100644
--- a/adev-ja/src/content/guide/aria/accordion.en.md
+++ b/adev-ja/src/content/guide/aria/accordion.en.md
@@ -145,13 +145,11 @@ Use the `ngAccordionContent` directive on an `ng-template` to defer rendering co
```angular-html
diff --git a/adev-ja/src/content/guide/aria/grid.en.md b/adev-ja/src/content/guide/aria/grid.en.md
index 2b162aee15..e91a02a4b3 100644
--- a/adev-ja/src/content/guide/aria/grid.en.md
+++ b/adev-ja/src/content/guide/aria/grid.en.md
@@ -135,11 +135,13 @@ Instead of tabbing through each button, users navigate with arrow keys and only
Enable selection with `[enableSelection]="true"` and configure how focus and selection interact.
```angular-html
-
diff --git a/adev-ja/src/content/guide/aria/listbox.en.md b/adev-ja/src/content/guide/aria/listbox.en.md
index d7a753a2d9..38238eb3e2 100644
--- a/adev-ja/src/content/guide/aria/listbox.en.md
+++ b/adev-ja/src/content/guide/aria/listbox.en.md
@@ -110,10 +110,21 @@ With `orientation="horizontal"`, left and right arrow keys navigate between opti
Listbox supports two selection modes that control when items become selected.
-
+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.
+
+#### Explicit
+
+
+
+
+
+
+#### Follow
+
+
+
+
+
| Mode | Description |
| ------------ | ------------------------------------------------------------------------------------------------------ |
diff --git a/adev-ja/src/content/guide/aria/listbox.md b/adev-ja/src/content/guide/aria/listbox.md
index e16c3ec507..8cc24a22e2 100644
--- a/adev-ja/src/content/guide/aria/listbox.md
+++ b/adev-ja/src/content/guide/aria/listbox.md
@@ -110,10 +110,21 @@ Angularのリストボックスは、以下の機能を備えた完全にアク
リストボックスは、アイテムがいつ選択されるかを制御する2つの選択モードをサポートしています。
-
+`'follow'`モードはフォーカスされたアイテムを自動的に選択し、選択が頻繁に変わる場合により速いインタラクションを提供します。`'explicit'`モードは選択を確定するためにSpaceキーまたはEnterキーが必要で、ナビゲーション中の意図しない変更を防ぎます。ドロップダウンパターンでは、通常、単一選択のために`'follow'`モードが使用されます。
+
+#### Explicit
+
+
+
+
+
+
+#### Follow
+
+
+
+
+
| モード | 説明 |
| ------------ | -------------------------------------------------------------------------------------- |
@@ -122,7 +133,7 @@ Angularのリストボックスは、以下の機能を備えた完全にアク
TIP: ドロップダウンパターンでは、通常、単一選択のために`'follow'`モードが使用されます。
-## API
+## API {#apis}
### Listboxディレクティブ {#listbox-directive}
diff --git a/adev-ja/src/content/guide/aria/menu.en.md b/adev-ja/src/content/guide/aria/menu.en.md
index 444325cfd2..fe69c67c6d 100644
--- a/adev-ja/src/content/guide/aria/menu.en.md
+++ b/adev-ja/src/content/guide/aria/menu.en.md
@@ -190,10 +190,9 @@ The container directive for menu items.
#### Methods
-| Method | Parameters | Description |
-| ---------------- | ---------- | ---------------------------------- |
-| `close` | none | Closes the menu |
-| `focusFirstItem` | none | Moves focus to the first menu item |
+| Method | Parameters | Description |
+| ------- | ---------- | --------------- |
+| `close` | none | Closes the menu |
### MenuBar
diff --git a/adev-ja/src/content/guide/aria/menu.md b/adev-ja/src/content/guide/aria/menu.md
index c9bbe91404..b0f1e8966a 100644
--- a/adev-ja/src/content/guide/aria/menu.md
+++ b/adev-ja/src/content/guide/aria/menu.md
@@ -190,10 +190,9 @@
#### メソッド {#methods}
-| Method | Parameters | Description |
-| ---------------- | ---------- | ---------------------------------- |
-| `close` | none | メニューを閉じます |
-| `focusFirstItem` | none | 最初のメニューアイテムにフォーカスを移動します |
+| Method | Parameters | Description |
+| ------- | ---------- | --------------- |
+| `close` | none | メニューを閉じます |
### MenuBar {#menubar}
diff --git a/adev-ja/src/content/guide/components/advanced-configuration.en.md b/adev-ja/src/content/guide/components/advanced-configuration.en.md
index 4e71034ee8..875e44ebab 100644
--- a/adev-ja/src/content/guide/components/advanced-configuration.en.md
+++ b/adev-ja/src/content/guide/components/advanced-configuration.en.md
@@ -40,7 +40,7 @@ import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
@Component({
...,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
- template: ''
+ template: ''
})
export class ComponentWithCustomElements { }
```
diff --git a/adev-ja/src/content/guide/components/advanced-configuration.md b/adev-ja/src/content/guide/components/advanced-configuration.md
index ffc6d52d9c..d33a1340eb 100644
--- a/adev-ja/src/content/guide/components/advanced-configuration.md
+++ b/adev-ja/src/content/guide/components/advanced-configuration.md
@@ -40,7 +40,7 @@ import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
@Component({
...,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
- template: ''
+ template: ''
})
export class ComponentWithCustomElements { }
```
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 c9732799a0..1bb8e6ae96 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
@@ -14,9 +14,9 @@ You provide Angular-specific information for a component by adding a `@Component
```angular-ts {highlight: [1, 2, 3, 4]}
@Component({
selector: 'profile-photo',
- template: ``,
+ template: ``,
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
For full details on writing Angular templates, including data binding, event handling, and control flow, see the [Templates guide](guide/templates).
@@ -28,10 +28,14 @@ Components can optionally include a list of CSS styles that apply to that compon
```angular-ts {highlight: [4]}
@Component({
selector: 'profile-photo',
- template: ``,
- styles: `img { border-radius: 50%; }`,
+ template: ``,
+ styles: `
+ img {
+ border-radius: 50%;
+ }
+ `,
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
By default, a component's styles only affect elements defined in that component's template. See [Styling Components](guide/components/styling) for details on Angular's approach to styling.
@@ -70,7 +74,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/overview) for details.
Important: In Angular versions before 19.0.0, the `standalone` option defaults to `false`.
@@ -94,13 +98,13 @@ You show a component by creating a matching HTML element in the template of _oth
@Component({
selector: 'profile-photo',
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
@Component({
-imports: [ProfilePhoto],
-template: ``
+ imports: [ProfilePhoto],
+ template: ``,
})
-export class UserProfile { }
+export class UserProfile {}
```
Angular creates an instance of the component for every matching HTML element it encounters. The DOM element that matches a component's selector is referred to as that component's **host element**. The contents of a component's template are rendered inside its host element.
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 53464d6882..ff31ad1d4d 100644
--- a/adev-ja/src/content/guide/components/anatomy-of-components.md
+++ b/adev-ja/src/content/guide/components/anatomy-of-components.md
@@ -14,9 +14,9 @@ TypeScriptクラスの上部に `@Component` [デコレーター](https://www.ty
```angular-ts {highlight: [1, 2, 3, 4]}
@Component({
selector: 'profile-photo',
- template: ``,
+ template: ``,
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
データバインディング、イベント処理、制御フローなど、Angularテンプレート作成に関する詳細は、[テンプレートガイド](guide/templates)を参照してください。
@@ -28,10 +28,14 @@ export class ProfilePhoto { }
```angular-ts {highlight: [4]}
@Component({
selector: 'profile-photo',
- template: ``,
- styles: `img { border-radius: 50%; }`,
+ template: ``,
+ styles: `
+ img {
+ border-radius: 50%;
+ }
+ `,
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
デフォルトでは、コンポーネントのスタイルは、そのコンポーネントのテンプレートで定義された要素にのみ影響を与えます。Angularのスタイリングアプローチの詳細については、[コンポーネントのスタイリング](guide/components/styling)を参照してください。
@@ -70,7 +74,7 @@ import {ProfilePhoto} from './profile-photo';
export class UserProfile {}
```
-デフォルトでは、Angularコンポーネントは*スタンドアロン*です。つまり、他のコンポーネントの`imports`配列に直接追加できます。以前のバージョンのAngularで作成されたコンポーネントは、代わりに`@Component`デコレーターで`standalone: false`を指定している場合があります。これらのコンポーネントの場合、代わりにコンポーネントが定義されている`NgModule`をインポートします。詳細は、完全な[`NgModule`ガイド](guide/ngmodules)を参照してください。
+デフォルトでは、Angularコンポーネントは*スタンドアロン*です。つまり、他のコンポーネントの`imports`配列に直接追加できます。以前のバージョンのAngularで作成されたコンポーネントは、代わりに`@Component`デコレーターで`standalone: false`を指定している場合があります。これらのコンポーネントの場合、代わりにコンポーネントが定義されている`NgModule`をインポートします。詳細は、完全な[`NgModule`ガイド](guide/ngmodules/overview)を参照してください。
IMPORTANT: 19.0.0より前のAngularバージョンでは、`standalone`オプションはデフォルトで`false`です。
@@ -83,7 +87,7 @@ IMPORTANT: 19.0.0より前のAngularバージョンでは、`standalone`オプ
selector: 'profile-photo',
...
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
Angularがサポートするセレクターの種類と、セレクターの選択に関するガイダンスについては、[コンポーネントセレクター](guide/components/selectors)を参照してください。
@@ -94,13 +98,13 @@ _他の_コンポーネントのテンプレートで一致するHTML要素を
@Component({
selector: 'profile-photo',
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
@Component({
-imports: [ProfilePhoto],
-template: ``
+ imports: [ProfilePhoto],
+ template: ``,
})
-export class UserProfile { }
+export class UserProfile {}
```
Angularは、遭遇する一致するHTML要素ごとにコンポーネントのインスタンスを作成します。コンポーネントのセレクターと一致するDOM要素は、そのコンポーネントの**ホスト要素**と呼ばれます。コンポーネントのテンプレートの内容はそのホスト要素内にレンダリングされます。
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 3fe55711f9..f11feb7f7f 100644
--- a/adev-ja/src/content/guide/components/content-projection.en.md
+++ b/adev-ja/src/content/guide/components/content-projection.en.md
@@ -10,7 +10,9 @@ example, you may want to create a custom card component:
selector: 'custom-card',
template: '
',
})
-export class CustomCard {/* ... */}
+export class CustomCard {
+ /* ... */
+}
```
**You can use the `` element as a placeholder to mark where content should go**:
@@ -20,7 +22,9 @@ export class CustomCard {/* ... */}
selector: 'custom-card',
template: '
',
})
-export class CustomCard {/* ... */}
+export class CustomCard {
+ /* ... */
+}
```
TIP: `` works similarly
@@ -40,7 +44,9 @@ rendered, or **projected**, at the location of that ``:
`,
})
-export class CustomCard {/* ... */}
+export class CustomCard {
+ /* ... */
+}
```
```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 1e84cc6cc2..ff4496994b 100644
--- a/adev-ja/src/content/guide/components/content-projection.md
+++ b/adev-ja/src/content/guide/components/content-projection.md
@@ -10,7 +10,9 @@ TIP: このガイドは、すでに [基本ガイド](essentials) を読んだ
selector: 'custom-card',
template: '
+
+ `,
+})
+export class DynamicCard {
+ private vcr = inject(ViewContainerRef);
+ cardComponent = CardWrapper;
+
+ private contentTemplate = viewChild>('contentTemplate');
+
+ cardContent = computed(() => {
+ const template = this.contentTemplate();
+ if (!template) return [];
+ // Returns an array of projection slots. Each element represents one slot.
+ // CardWrapper has one , so we return an array with one element.
+ return [this.vcr.createEmbeddedView(template).rootNodes];
+ });
+}
+```
+
+NOTE: Hydration does not support projecting DOM nodes created with native DOM APIs. This causes an [NG0503 error](/errors/NG0503). Use Angular APIs to create projected content or add `ngSkipHydration` to the component.
+
+### Providing injectors
+
+You can provide a custom injector to the dynamically created component using `ngComponentOutletInjector`. This is useful for providing component-specific services or configuration.
+
+```angular-ts
+export const THEME_DATA = new InjectionToken('THEME_DATA', {
+ factory: () => 'light',
+});
+
+@Component({
+ selector: 'themed-panel',
+ template: `
...
`,
+})
+export class ThemedPanel {
+ theme = inject(THEME_DATA);
+}
+
+@Component({
+ selector: 'dynamic-panel',
+ imports: [NgComponentOutlet],
+ template: ``,
+})
+export class DynamicPanel {
+ panelComponent = ThemedPanel;
+
+ customInjector = Injector.create({
+ providers: [{provide: THEME_DATA, useValue: 'dark'}],
+ });
+}
+```
+
+### Accessing the component instance
+
+You can access the dynamically created component's instance using the directive's `exportAs` feature:
+
+```angular-ts
+@Component({
+ selector: 'counter',
+ template: `
Count: {{ count() }}
`,
+})
+export class Counter {
+ count = signal(0);
+ increment() {
+ this.count.update((c) => c + 1);
+ }
+}
+
+@Component({
+ imports: [NgComponentOutlet],
+ template: `
+
+
+
+ `,
+})
+export class CounterHost {
+ counterComponent = Counter;
+}
+```
+
+NOTE: The `componentInstance` property is `null` before the component is rendered.
+
See the [NgComponentOutlet API reference](api/common/NgComponentOutlet) for more information on the
directive's capabilities.
@@ -57,9 +195,7 @@ DOM as the next sibling of the component or directive that injected the `ViewCon
```angular-ts
@Component({
selector: 'leaf-content',
- template: `
- This is the leaf content
- `,
+ template: `This is the leaf content`,
})
export class LeafContent {}
@@ -75,9 +211,7 @@ export class OuterContainer {}
@Component({
selector: 'inner-item',
- template: `
-
- `,
+ template: ``,
})
export class InnerItem {
private viewContainer = inject(ViewContainerRef);
@@ -153,20 +287,20 @@ To simplify this, both `createComponent` and `ViewContainerRef.createComponent`
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";
+import {Component, input, model, output} from '@angular/core';
@Component({
selector: 'app-warning',
template: `
- @if(isExpanded()) {
-
-
Warning: Action needed!
-
-
- }
- `
+ @if (isExpanded()) {
+
+
Warning: Action needed!
+
+
+ }
+ `,
})
-export class AppWarningComponent {
+export class AppWarning {
readonly canClose = input.required();
readonly isExpanded = model();
readonly close = output();
@@ -189,13 +323,13 @@ import {ThemeDirective} from '../theme.directive';
@Component({
template: ``,
})
-export class HostComponent {
+export class Host {
private vcr = inject(ViewContainerRef);
readonly canClose = signal(true);
readonly isExpanded = signal(true);
showWarning() {
- const compRef = this.vcr.createComponent(AppWarningComponent, {
+ const compRef = this.vcr.createComponent(AppWarning, {
bindings: [
inputBinding('canClose', this.canClose),
twoWayBinding('isExpanded', this.isExpanded),
@@ -212,7 +346,7 @@ export class HostComponent {
}
```
-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`.
+In the example above, the dynamic **AppWarning** 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`
@@ -228,7 +362,7 @@ import {
inputBinding,
outputBinding,
} from '@angular/core';
-import {PopupComponent} from './popup.component';
+import {Popup} from './popup';
@Injectable({providedIn: 'root'})
export class PopupService {
@@ -240,7 +374,7 @@ export class PopupService {
const host = document.createElement('popup-host');
// Create the component and bind in one call
- const ref = createComponent(PopupComponent, {
+ const ref = createComponent(Popup, {
environmentInjector: this.injector,
hostElement: host,
bindings: [
diff --git a/adev-ja/src/content/guide/components/programmatic-rendering.md b/adev-ja/src/content/guide/components/programmatic-rendering.md
index 1d7631d64f..2c5851e30f 100644
--- a/adev-ja/src/content/guide/components/programmatic-rendering.md
+++ b/adev-ja/src/content/guide/components/programmatic-rendering.md
@@ -20,10 +20,10 @@ HELPFUL: 遅延読み込みのユースケース(たとえば、重いコンポ
構造ディレクティブです。
```angular-ts
-@Component({ ... })
+@Component({/*...*/})
export class AdminBio { /* ... */ }
-@Component({ ... })
+@Component({/*...*/})
export class StandardBio { /* ... */ }
@Component({
@@ -41,6 +41,144 @@ export class CustomDialog {
}
```
+### 動的にレンダリングされたコンポーネントへのインプットの渡し方
+
+`ngComponentOutletInputs`プロパティを使用して、動的にレンダリングされたコンポーネントにインプットを渡すことができます。このプロパティは、キーがインプット名で値がインプット値であるオブジェクトを受け入れます。
+
+```angular-ts
+@Component({
+ selector: 'user-greeting',
+ template: `
+
+
+
+ }
+ `,
})
-export class AppWarningComponent {
+export class AppWarning {
readonly canClose = input.required();
readonly isExpanded = model();
readonly close = output();
@@ -189,13 +323,13 @@ import {ThemeDirective} from '../theme.directive';
@Component({
template: ``,
})
-export class HostComponent {
+export class Host {
private vcr = inject(ViewContainerRef);
readonly canClose = signal(true);
readonly isExpanded = signal(true);
showWarning() {
- const compRef = this.vcr.createComponent(AppWarningComponent, {
+ const compRef = this.vcr.createComponent(AppWarning, {
bindings: [
inputBinding('canClose', this.canClose),
twoWayBinding('isExpanded', this.isExpanded),
@@ -212,7 +346,7 @@ export class HostComponent {
}
```
-上記の例では、動的な**AppWarningComponent**は、`canClose`インプットがリアクティブシグナルにバインドされ、`isExpanded`状態で双方向バインディングが行われ、`close`のアウトプットリスナーが設定されて作成されます。`FocusTrap`と`ThemeDirective`は、`directives`を介してホスト要素にアタッチされます。
+上記の例では、動的な**AppWarning**は、`canClose`インプットがリアクティブシグナルにバインドされ、`isExpanded`状態で双方向バインディングが行われ、`close`のアウトプットリスナーが設定されて作成されます。`FocusTrap`と`ThemeDirective`は、`directives`を介してホスト要素にアタッチされます。
### `createComponent` + `hostElement`で`document.body`にアタッチされたポップアップ
@@ -228,7 +362,7 @@ import {
inputBinding,
outputBinding,
} from '@angular/core';
-import {PopupComponent} from './popup.component';
+import {Popup} from './popup';
@Injectable({providedIn: 'root'})
export class PopupService {
@@ -240,7 +374,7 @@ export class PopupService {
const host = document.createElement('popup-host');
// コンポーネントを作成し、1回の呼び出しでバインド
- const ref = createComponent(PopupComponent, {
+ const ref = createComponent(Popup, {
environmentInjector: this.injector,
hostElement: host,
bindings: [
diff --git a/adev-ja/src/content/guide/components/queries.en.md b/adev-ja/src/content/guide/components/queries.en.md
index 512067b0fa..b76607661f 100644
--- a/adev-ja/src/content/guide/components/queries.en.md
+++ b/adev-ja/src/content/guide/components/queries.en.md
@@ -58,7 +58,7 @@ export class CustomCardAction {
})
export class CustomCard {
actions = viewChildren(CustomCardAction);
- actionsTexts = computed(() => this.actions().map(action => action.text));
+ actionsTexts = computed(() => this.actions().map((action) => action.text));
}
```
@@ -89,16 +89,15 @@ export class CustomExpando {
}
@Component({
-/* ... */
-// CustomToggle is used inside CustomExpando as content.
-template: `
+ /* ... */
+ // CustomToggle is used inside CustomExpando as content.
+ template: `
Show
- `
+ `,
})
-
-export class UserProfile { }
+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.
@@ -107,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.
-```angular-ts {highlight: [14, 16, 17, 18, 19, 20]}
+```angular-ts {highlight: [14, 15]}
@Component({
selector: 'custom-menu-item',
/*...*/
@@ -120,10 +119,9 @@ export class CustomMenuItem {
selector: 'custom-menu',
/*...*/
})
-
export class CustomMenu {
items = contentChildren(CustomMenuItem);
- itemTexts = computed(() => this.items().map(item => item.text));
+ itemTexts = computed(() => this.items().map((item) => item.text));
}
@Component({
@@ -133,9 +131,9 @@ export class CustomMenu {
CheeseTomato
- `
+ `,
})
-export class UserProfile { }
+export class UserProfile {}
```
`contentChildren` creates a signal with an `Array` of the query results.
@@ -150,7 +148,7 @@ In some cases, especially with `viewChild`, you know with certainty that a speci
```ts
@Component({
- /* ... */
+ /*...*/
})
export class CustomCard {
header = viewChild.required(CustomCardHeader);
@@ -175,7 +173,7 @@ a [template reference variable](guide/templates/variables#template-reference-var
template: `
- `
+ `,
})
export class ActionBar {
saveButton = viewChild>('save');
@@ -199,9 +197,11 @@ const SUB_ITEM = new InjectionToken('sub-item');
/*...*/
providers: [{provide: SUB_ITEM, useValue: 'special-item'}],
})
-export class SpecialItem { }
+export class SpecialItem {}
-@Component({/*...*/})
+@Component({
+ /*...*/
+})
export class CustomList {
subItemType = contentChild(SUB_ITEM);
}
@@ -236,7 +236,7 @@ Developers most commonly use `read` to retrieve `ElementRef` and `TemplateRef`.
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.
-```angular-ts {highlight: [13, 14, 15, 16]}
+```angular-ts {highlight: [13, 14, 15, 16, 17]}
@Component({
selector: 'custom-expando',
/*...*/
@@ -254,9 +254,9 @@ export class CustomExpando {
Show
- `
+ `,
})
-export class UserProfile { }
+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.
@@ -287,7 +287,7 @@ export class CustomCardHeader {
selector: 'custom-card',
template: 'Visit sunny California!',
})
-export class CustomCard {
+export class CustomCard implements AfterViewInit {
@ViewChild(CustomCardHeader) header: CustomCardHeader;
ngAfterViewInit() {
@@ -320,11 +320,11 @@ export class CustomCardAction {
Cancel
`,
})
-export class CustomCard {
+export class CustomCard implements AfterViewInit {
@ViewChildren(CustomCardAction) actions: QueryList;
ngAfterViewInit() {
- this.actions.forEach(action => {
+ this.actions.forEach((action) => {
console.log(action.text);
});
}
@@ -337,7 +337,7 @@ export class CustomCard {
You can query for a single result with the `@ContentChild` decorator.
-```angular-ts {highlight: [15, 16, 17, 18, 19, 26]}
+```angular-ts {highlight: [14, 16, 17, 18]}
@Component({
selector: 'custom-toggle',
/*...*/
@@ -350,8 +350,7 @@ export class CustomToggle {
selector: 'custom-expando',
/*...*/
})
-
-export class CustomExpando {
+export class CustomExpando implements AfterContentInit {
@ContentChild(CustomToggle) toggle: CustomToggle;
ngAfterContentInit() {
@@ -365,9 +364,9 @@ export class CustomExpando {
Show
- `
+ `,
})
-export class UserProfile { }
+export class UserProfile {}
```
In this example, the `CustomExpando` component queries for a child `CustomToggle` and accesses the result in `ngAfterContentInit`.
@@ -378,7 +377,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.
-```angular-ts {highlight: [15, 17, 18, 19, 20, 21]}
+```angular-ts {highlight: [14, 16, 17, 18, 19, 20]}
@Component({
selector: 'custom-menu-item',
/*...*/
@@ -391,12 +390,11 @@ export class CustomMenuItem {
selector: 'custom-menu',
/*...*/
})
-
-export class CustomMenu {
+export class CustomMenu implements AfterContentInit {
@ContentChildren(CustomMenuItem) items: QueryList;
ngAfterContentInit() {
- this.items.forEach(item => {
+ this.items.forEach((item) => {
console.log(item.text);
});
}
@@ -409,9 +407,9 @@ export class CustomMenu {
CheeseTomato
- `
+ `,
})
-export class UserProfile { }
+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.
@@ -429,7 +427,7 @@ All query decorators accept an options object as a second parameter. These optio
selector: 'custom-card',
template: 'Visit sunny California!',
})
-export class CustomCard {
+export class CustomCard implements OnInit {
@ViewChild(CustomCardHeader, {static: true}) header: CustomCardHeader;
ngOnInit() {
diff --git a/adev-ja/src/content/guide/components/queries.md b/adev-ja/src/content/guide/components/queries.md
index 4be5c09f5b..1b233b4728 100644
--- a/adev-ja/src/content/guide/components/queries.md
+++ b/adev-ja/src/content/guide/components/queries.md
@@ -11,7 +11,7 @@ TIP: このガイドでは、[基本概念のガイド](essentials)を読んで
クエリには、**ビュークエリ**と**コンテンツクエリ**の2つのカテゴリーがあります。
-## ビュークエリ
+## ビュークエリ {#view-queries}
ビュークエリは、コンポーネントの_ビュー_(コンポーネント自身のテンプレートで定義された要素)内の要素から結果を取得します。`viewChild`関数を使用して単一の結果をクエリできます。
@@ -58,7 +58,7 @@ export class CustomCardAction {
})
export class CustomCard {
actions = viewChildren(CustomCardAction);
- actionsTexts = computed(() => this.actions().map(action => action.text));
+ actionsTexts = computed(() => this.actions().map((action) => action.text));
}
```
@@ -66,7 +66,7 @@ export class CustomCard {
**クエリはコンポーネントの境界を貫通することはありません。**ビュークエリは、コンポーネントのテンプレートからの結果のみを取得できます。
-## コンテンツクエリ
+## コンテンツクエリ {#content-queries}
コンテンツクエリは、コンポーネントの_コンテンツ_(コンポーネントが使用されているテンプレート内でコンポーネントの中にネストされた要素)内の要素から結果を取得します。`contentChild`関数を使用して単一の結果をクエリできます。
@@ -89,16 +89,15 @@ export class CustomExpando {
}
@Component({
-/* ... */
-// CustomToggle is used inside CustomExpando as content.
-template: `
+ /* ... */
+ // CustomToggle is used inside CustomExpando as content.
+ template: `
Show
- `
+ `,
})
-
-export class UserProfile { }
+export class UserProfile {}
```
クエリが結果を見つけられない場合、その値は`undefined`になります。これは、ターゲット要素が存在しないか、`@if`によって非表示になっている場合に発生する可能性があります。Angularは、アプリケーションの状態が変化するにつれて`contentChild`の結果を最新の状態に保ちます。
@@ -107,7 +106,7 @@ export class UserProfile { }
`contentChildren`関数を使用して、複数結果をクエリできます。
-```angular-ts {highlight: [14, 16, 17, 18, 19, 20]}
+```angular-ts {highlight: [14, 15]}
@Component({
selector: 'custom-menu-item',
/* ... */
@@ -120,10 +119,9 @@ export class CustomMenuItem {
selector: 'custom-menu',
/* ... */
})
-
export class CustomMenu {
items = contentChildren(CustomMenuItem);
- itemTexts = computed(() => this.items().map(item => item.text));
+ itemTexts = computed(() => this.items().map((item) => item.text));
}
@Component({
@@ -133,9 +131,9 @@ export class CustomMenu {
CheeseTomato
- `
+ `,
})
-export class UserProfile { }
+export class UserProfile {}
```
`contentChildren`は、クエリ結果の`Array`を含むシグナルを作成します。
@@ -150,7 +148,7 @@ export class UserProfile { }
```ts
@Component({
- /* ... */
+ /*...*/
})
export class CustomCard {
header = viewChild.required(CustomCardHeader);
@@ -175,7 +173,7 @@ export class CustomCard {
template: `
- `
+ `,
})
export class ActionBar {
saveButton = viewChild>('save');
@@ -199,7 +197,7 @@ const SUB_ITEM = new InjectionToken('sub-item');
/*...*/
providers: [{provide: SUB_ITEM, useValue: 'special-item'}],
})
-export class SpecialItem { }
+export class SpecialItem {}
@Component({/*...*/})
export class CustomList {
@@ -287,7 +285,7 @@ export class CustomCardHeader {
selector: 'custom-card',
template: 'Visit sunny California!',
})
-export class CustomCard {
+export class CustomCard implements AfterViewInit {
@ViewChild(CustomCardHeader) header: CustomCardHeader;
ngAfterViewInit() {
diff --git a/adev-ja/src/content/guide/components/selectors.en.md b/adev-ja/src/content/guide/components/selectors.en.md
index 8539c7f18c..a04926ba08 100644
--- a/adev-ja/src/content/guide/components/selectors.en.md
+++ b/adev-ja/src/content/guide/components/selectors.en.md
@@ -140,7 +140,7 @@ without extra work. This is especially valuable for ARIA attributes such as `ari
Angular does not report errors when it encounters custom attributes that don't match an available
component. When using components with attribute selectors, consumers may forget to import the
component or its NgModule, resulting in the component not rendering.
-See [Importing and using components](guide/components/importing) for more information.
+See [Importing and using components](guide/components#imports-in-the-component-decorator) for more information.
Components that define attribute selectors should use lowercase, dash-case attributes. You can
follow the same prefixing recommendation described above.
diff --git a/adev-ja/src/content/guide/components/selectors.md b/adev-ja/src/content/guide/components/selectors.md
index 9e0654c4de..628f51a6bd 100644
--- a/adev-ja/src/content/guide/components/selectors.md
+++ b/adev-ja/src/content/guide/components/selectors.md
@@ -98,7 +98,7 @@ export class DropZone { }
Angularは、リスト内の_いずれか_のセレクターにマッチングする要素ごとにコンポーネントを作成します。
-## セレクターの選択
+## セレクターの選択 {#choosing-a-selector}
ほとんどのコンポーネントは、カスタム要素名をセレクターとして使用する必要があります。
すべてのカスタム要素名は、
@@ -110,7 +110,7 @@ Angularテンプレートで
[ネイティブ カスタム要素](https://developer.mozilla.org/docs/Web/Web_Components) を使用する方法の詳細については、
[コンポーネントの高度な設定](guide/components/advanced-configuration) を参照してください。
-### セレクターのプレフィックス
+### セレクターのプレフィックス {#selector-prefixes}
Angularチームは、プロジェクト内で定義されているすべてのカスタムコンポーネントに
短い一貫性のあるプレフィックスを使用することをお勧めします。
@@ -140,7 +140,7 @@ export class YouTubeUploadButton { }
Angularは、使用可能なコンポーネントと一致しないカスタム属性に出会ってもエラーを報告しません。
属性セレクターを使用してコンポーネントを使用する場合、
利用者はコンポーネントまたはそのNgModuleをインポートし忘れることがあり、その結果、コンポーネントがレンダリングされません。
-詳細については、[コンポーネントのインポートと使用](guide/components/importing) を参照してください。
+詳細については、[コンポーネントのインポートと使用](guide/components#imports-in-the-component-decorator) を参照してください。
属性セレクターを定義するコンポーネントは、小文字、ダッシュ区切りの属性を使用する必要があります。
上記で説明したプレフィックスの推奨事項に従うことができます。
diff --git a/adev-ja/src/content/guide/components/styling.en.md b/adev-ja/src/content/guide/components/styling.en.md
index 0f00e7485c..0355304f27 100644
--- a/adev-ja/src/content/guide/components/styling.en.md
+++ b/adev-ja/src/content/guide/components/styling.en.md
@@ -7,10 +7,14 @@ Components can optionally include CSS styles that apply to that component's DOM:
```angular-ts {highlight:[4]}
@Component({
selector: 'profile-photo',
- template: ``,
- styles: ` img { border-radius: 50%; } `,
+ template: ``,
+ styles: `
+ img {
+ border-radius: 50%;
+ }
+ `,
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
You can also choose to write your styles in separate files:
@@ -21,7 +25,7 @@ You can also choose to write your styles in separate files:
templateUrl: 'profile-photo.html',
styleUrl: 'profile-photo.css',
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
When Angular compiles your component, these styles are emitted with your component's JavaScript
diff --git a/adev-ja/src/content/guide/components/styling.md b/adev-ja/src/content/guide/components/styling.md
index a685843ade..c8dca8ca99 100644
--- a/adev-ja/src/content/guide/components/styling.md
+++ b/adev-ja/src/content/guide/components/styling.md
@@ -7,10 +7,14 @@ TIP: このガイドでは、すでに[基本概念のガイド](essentials)を
```angular-ts {highlight:[4]}
@Component({
selector: 'profile-photo',
- template: ``,
- styles: ` img { border-radius: 50%; } `,
+ template: ``,
+ styles: `
+ img {
+ border-radius: 50%;
+ }
+ `,
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
また、別のファイルにスタイルを記述できます。
@@ -21,7 +25,7 @@ export class ProfilePhoto { }
templateUrl: 'profile-photo.html',
styleUrl: 'profile-photo.css',
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
Angularがコンポーネントをコンパイルすると、これらのスタイルはコンポーネントのJavaScript出力と共に発行されます。
@@ -33,7 +37,7 @@ Angularは、[Sass](https://sass-lang.com)、
[less](https://lesscss.org)、[stylus](https://stylus-lang.com)など、
CSSを出力するすべてのツールと連携します。
-## スタイルのスコープ
+## スタイルのスコープ {#style-scoping}
各コンポーネントには、**ビューカプセル化**設定があり、フレームワークがコンポーネントのスタイルをどのようにスコープするかを決定します。
ビューカプセル化モードには、`Emulated`、`ShadowDom`、`ExperimentalIsolatedShadowDom`、`None`の4つのモードがあります。
@@ -44,7 +48,7 @@ CSSを出力するすべてのツールと連携します。
...,
encapsulation: ViewEncapsulation.None,
})
-export class ProfilePhoto { }
+export class ProfilePhoto {}
```
### ViewEncapsulation.Emulated
diff --git a/adev-ja/src/content/guide/di/creating-and-using-services.en.md b/adev-ja/src/content/guide/di/creating-and-using-services.en.md
index d7b1486f6a..a9cdc05328 100644
--- a/adev-ja/src/content/guide/di/creating-and-using-services.en.md
+++ b/adev-ja/src/content/guide/di/creating-and-using-services.en.md
@@ -51,21 +51,19 @@ Once you've created a service with `providedIn: 'root'`, you can inject it anywh
### Injecting into a component
```angular-ts
-import { Component, inject } from '@angular/core';
-import { BasicDataStore } from './basic-data-store';
+import {Component, inject} from '@angular/core';
+import {BasicDataStore} from './basic-data-store';
@Component({
selector: 'app-example',
template: `
{{ dataStore.getData() }}
-
+
- `
+ `,
})
-export class ExampleComponent {
+export class Example {
dataStore = inject(BasicDataStore);
}
```
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
index 02236a8ff4..742fcc2290 100644
--- a/adev-ja/src/content/guide/di/creating-and-using-services.md
+++ b/adev-ja/src/content/guide/di/creating-and-using-services.md
@@ -51,21 +51,19 @@ export class BasicDataStore {
### コンポーネントへの注入 {#injecting-into-a-component}
```angular-ts
-import { Component, inject } from '@angular/core';
-import { BasicDataStore } from './basic-data-store';
+import {Component, inject} from '@angular/core';
+import {BasicDataStore} from './basic-data-store';
@Component({
selector: 'app-example',
template: `
{{ dataStore.getData() }}
-
+
- `
+ `,
})
-export class ExampleComponent {
+export class Example {
dataStore = inject(BasicDataStore);
}
```
diff --git a/adev-ja/src/content/guide/di/creating-injectable-service.md b/adev-ja/src/content/guide/di/creating-injectable-service.md
index 1dad19288e..30123b8a65 100644
--- a/adev-ja/src/content/guide/di/creating-injectable-service.md
+++ b/adev-ja/src/content/guide/di/creating-injectable-service.md
@@ -108,20 +108,20 @@ For clarity and maintainability, it is recommended that you define components an
To inject a service as a dependency into a component, you can declare a class field representing the dependency and use Angular's [`inject`](/api/core/inject) function to initialize it.
-The following example specifies the `HeroService` in the `HeroListComponent`.
+The following example specifies the `HeroService` in the `HeroList`.
The type of `heroService` is `HeroService`.
```ts
import {inject} from '@angular/core';
-export class HeroListComponent {
+export class HeroList {
private heroService = inject(HeroService);
}
```
It is also possible to inject a service into a component using the component's constructor:
-```ts {header: 'hero-list.component.ts (constructor signature)'}
+```ts {header: 'hero-list.ts (constructor signature)'}
constructor(private heroService: HeroService)
```
@@ -155,6 +155,6 @@ In this example, the `getHeroes()` method uses the `Logger` service by logging a
## What's next
-
-
+
+
diff --git a/adev-ja/src/content/guide/di/debugging-and-troubleshooting-di.md b/adev-ja/src/content/guide/di/debugging-and-troubleshooting-di.md
new file mode 100644
index 0000000000..e5f9ae9644
--- /dev/null
+++ b/adev-ja/src/content/guide/di/debugging-and-troubleshooting-di.md
@@ -0,0 +1,1018 @@
+# Debugging and troubleshooting dependency injection
+
+Dependency injection (DI) issues typically stem from configuration mistakes, scope problems, or incorrect usage patterns. This guide helps you identify and resolve common DI problems that developers encounter.
+
+## Common pitfalls and solutions
+
+### Services not available where expected
+
+One of the most common DI issues occurs when you try to inject a service but Angular cannot find it in the current injector or any parent injector. This usually happens when the service is provided in the wrong scope or not provided at all.
+
+#### Provider scope mismatch
+
+When you provide a service in a component's `providers` array, Angular creates an instance in that component's injector. This instance is only available to that component and its children. Parent components and sibling components cannot access it because they use different injectors.
+
+```angular-ts {header: 'child-view.ts'}
+import {Component} from '@angular/core';
+import {DataStore} from './data-store';
+
+@Component({
+ selector: 'app-child',
+ template: '
Child
',
+ providers: [DataStore], // Only available in this component and its children
+})
+export class ChildView {}
+```
+
+```angular-ts {header: 'parent-view.ts'}
+import {Component, inject} from '@angular/core';
+import {DataStore} from './data-store';
+
+@Component({
+ selector: 'app-parent',
+ template: '',
+})
+export class ParentView {
+ private dataService = inject(DataStore); // ERROR: Not available to parent
+}
+```
+
+Angular only searches up the hierarchy, never down. Parent components cannot access services provided in child components.
+
+**Solution:** Provide the service at a higher level (application or parent component).
+
+```ts {prefer}
+import {Injectable} from '@angular/core';
+
+@Injectable({providedIn: 'root'})
+export class DataStore {
+ // Available everywhere
+}
+```
+
+TIP: Use `providedIn: 'root'` by default for services that don't need component-specific state. This makes services available everywhere and enables tree-shaking.
+
+#### Services and lazy-loaded routes
+
+When you provide a service in a lazy-loaded route's `providers` array, Angular creates a child injector for that route. This injector and its services only become available after the route loads. Components in the eagerly-loaded parts of your application cannot access these services because they use different injectors that exist before the lazy-loaded injector is created.
+
+```ts {header: 'feature.routes.ts'}
+import {Routes} from '@angular/router';
+import {FeatureClient} from './feature-client';
+
+export const featureRoutes: Routes = [
+ {
+ path: 'feature',
+ providers: [FeatureClient],
+ loadComponent: () => import('./feature-view'),
+ },
+];
+```
+
+```angular-ts {header: 'eager-view.ts'}
+import {Component, inject} from '@angular/core';
+import {FeatureClient} from './feature-client';
+
+@Component({
+ selector: 'app-eager',
+ template: '
Eager Component
',
+})
+export class EagerView {
+ private featureService = inject(FeatureClient); // ERROR: Not available yet
+}
+```
+
+Lazy-loaded routes create child injectors that are only available after the route loads.
+
+NOTE: By default, route injectors and their services persist even after navigating away from the route. They are not destroyed until the application is closed. For automatic cleanup of unused route injectors, see [customizing route behavior](guide/routing/customizing-route-behavior#experimental-automatic-cleanup-of-unused-route-injectors).
+
+**Solution:** Use `providedIn: 'root'` for services that need to be shared across lazy boundaries.
+
+```ts {prefer, header: 'Provide at root for shared services'}
+import {Injectable} from '@angular/core';
+
+@Injectable({providedIn: 'root'})
+export class FeatureClient {
+ // Available everywhere, including before lazy load
+}
+```
+
+If the service should be lazy-loaded but still available to eager components, inject it only where needed and use optional injection to handle availability.
+
+### Multiple instances instead of singletons
+
+You expect one shared instance (singleton) but get separate instances in different components.
+
+#### Providing in component instead of root
+
+When you add a service to a component's `providers` array, Angular creates a new instance of that service for each instance of the component. Each component gets its own separate service instance, which means changes in one component don't affect the service instance in other components. This is often unexpected when you want shared state across your application.
+
+```angular-ts {avoid, header: 'Component-level provider creates multiple instances'}
+import {Component, inject} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-profile',
+ template: '
Profile
',
+ providers: [UserClient], // Creates new instance per component!
+})
+export class UserProfile {
+ private userService = inject(UserClient);
+}
+
+@Component({
+ selector: 'app-settings',
+ template: '
Settings
',
+ providers: [UserClient], // Different instance!
+})
+export class UserSettings {
+ private userService = inject(UserClient);
+}
+```
+
+Each component gets its own `UserClient` instance. Changes in one component don't affect the other.
+
+**Solution:** Use `providedIn: 'root'` for singletons.
+
+```ts {prefer, header: 'Root-level singleton'}
+import {Injectable} from '@angular/core';
+
+@Injectable({providedIn: 'root'})
+export class UserClient {
+ // Single instance shared across all components
+}
+```
+
+#### When multiple instances are intentional
+
+Sometimes you want separate instances per component for component-specific state.
+
+```angular-ts {header: 'Intentional: Component-scoped state'}
+import {Injectable, signal} from '@angular/core';
+
+@Injectable() // No providedIn - must be provided explicitly
+export class FormStateStore {
+ private formData = signal({});
+
+ setData(data: any) {
+ this.formData.set(data);
+ }
+
+ getData() {
+ return this.formData();
+ }
+}
+
+@Component({
+ selector: 'app-user-form',
+ template: '',
+ providers: [FormStateStore], // Each form gets its own state
+})
+export class UserForm {
+ private formState = inject(FormStateStore);
+}
+```
+
+This pattern is useful for:
+
+- Form state management (each form has isolated state)
+- Component-specific caching
+- Temporary data that shouldn't be shared
+
+### Incorrect inject() usage
+
+The `inject()` function only works in specific contexts during class construction and factory execution.
+
+#### Using inject() in lifecycle hooks
+
+When you call the `inject()` function inside lifecycle hooks like `ngOnInit()`, `ngAfterViewInit()`, or `ngOnDestroy()`, Angular throws an error because these methods run outside the injection context. The injection context is only available during the synchronous execution of class construction, which happens before lifecycle hooks are called.
+
+```angular-ts {avoid, header: 'inject() in ngOnInit'}
+import {Component, inject} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-profile',
+ template: '
User: {{userName}}
',
+})
+export class UserProfile {
+ userName = '';
+
+ ngOnInit() {
+ const userService = inject(UserClient); // ERROR: Not an injection context
+ this.userName = userService.getUser().name;
+ }
+}
+```
+
+**Solution:** Capture dependencies and derive values in field initializers.
+
+```angular-ts {prefer, header: 'Derive values in field initializers'}
+import {Component, inject} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-profile',
+ template: '
User: {{userName}}
',
+})
+export class UserProfile {
+ private userService = inject(UserClient);
+ userName = this.userService.getUser().name;
+}
+```
+
+#### Using the Injector for deferred injection
+
+When you need to retrieve services outside an injection context, use the captured `Injector` directly with `injector.get()`:
+
+```angular-ts
+import {Component, inject, Injector} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-profile',
+ template: '',
+})
+export class UserProfile {
+ private injector = inject(Injector);
+
+ delayedLoad() {
+ setTimeout(() => {
+ const userService = this.injector.get(UserClient);
+ console.log(userService.getUser());
+ }, 1000);
+ }
+}
+```
+
+#### Using runInInjectionContext for callbacks
+
+Use `runInInjectionContext()` when you need to enable **other code** to call `inject()`. This is useful when accepting callbacks that might use dependency injection:
+
+```angular-ts
+import {Component, inject, Injector, input} from '@angular/core';
+
+@Component({
+ selector: 'app-data-loader',
+ template: '',
+})
+export class DataLoader {
+ private injector = inject(Injector);
+ onLoad = input<() => void>();
+
+ load() {
+ const callback = this.onLoad();
+ if (callback) {
+ // Enable the callback to use inject()
+ this.injector.runInInjectionContext(callback);
+ }
+ }
+}
+```
+
+The `runInInjectionContext()` method creates a temporary injection context, allowing code inside the callback to call `inject()`.
+
+IMPORTANT: Always capture dependencies at the class level when possible. Use `injector.get()` for simple deferred retrieval, and `runInInjectionContext()` only when external code needs to call `inject()`.
+
+TIP: Use `assertInInjectionContext()` to verify your code is running in a valid injection context. This is useful when creating reusable functions that call `inject()`. See [Asserting the context](guide/di/dependency-injection-context#asserts-the-context) for details.
+
+### providers vs viewProviders confusion
+
+The difference between `providers` and `viewProviders` affects content projection scenarios.
+
+#### Understanding the difference
+
+**providers:** Available to the component's template AND any content projected into the component (ng-content).
+
+**viewProviders:** Only available to the component's template, NOT to projected content.
+
+```angular-ts {header: 'parent-view.ts'}
+import {Component, inject} from '@angular/core';
+import {ThemeStore} from './theme-store';
+
+@Component({
+ selector: 'app-parent',
+ template: `
+
+
Theme: {{ themeService.theme() }}
+
+
+ `,
+ providers: [ThemeStore], // Available to content children
+})
+export class ParentView {
+ protected themeService = inject(ThemeStore);
+}
+
+@Component({
+ selector: 'app-parent-view',
+ template: `
+
+
Theme: {{ themeService.theme() }}
+
+
+ `,
+ viewProviders: [ThemeStore], // NOT available to content children
+})
+export class ParentViewOnly {
+ protected themeService = inject(ThemeStore);
+}
+```
+
+```angular-ts {header: 'child-view.ts'}
+import {Component, inject} from '@angular/core';
+import {ThemeStore} from './theme-store';
+
+@Component({
+ selector: 'app-child',
+ template: '
Child theme: {{theme()}}
',
+})
+export class ChildView {
+ private themeService = inject(ThemeStore, {optional: true});
+ theme = () => this.themeService?.theme() ?? 'none';
+}
+```
+
+```angular-ts {header: 'app.ts'}
+@Component({
+ selector: 'app-root',
+ template: `
+
+
+
+
+
+
+
+
+
+ `,
+})
+export class App {}
+```
+
+**When projected into `app-parent`:** The child component can inject `ThemeStore` because `providers` makes it available to projected content.
+
+**When projected into `app-parent-view`:** The child component cannot inject `ThemeStore` because `viewProviders` restricts it to the parent's template only.
+
+#### Choosing between providers and viewProviders
+
+Use `providers` when:
+
+- The service should be available to projected content
+- You want content children to access the service
+- You're providing general-purpose services
+
+Use `viewProviders` when:
+
+- The service should only be available to your component's template
+- You want to hide implementation details from projected content
+- You're providing internal services that shouldn't leak out
+
+**Default recommendation:** Use `providers` unless you have a specific reason to restrict access with `viewProviders`.
+
+### InjectionToken issues
+
+When using `InjectionToken` for non-class dependencies, developers often encounter problems related to token identity, type safety, and provider configuration. These issues usually stem from how JavaScript handles object identity and how TypeScript infers types.
+
+#### Token identity confusion
+
+When you create a new `InjectionToken` instance, JavaScript creates a unique object in memory. Even if you create another `InjectionToken` with the exact same description string, it's a completely different object. Angular uses the token object's identity (not its description) to match providers with injection points, so tokens with the same description but different object identities cannot access each other's values.
+
+```ts {header: 'config.token.ts'}
+import {InjectionToken} from '@angular/core';
+
+export interface AppConfig {
+ apiUrl: string;
+}
+
+export const APP_CONFIG = new InjectionToken('app config');
+```
+
+```ts {header: 'app.config.ts'}
+import {APP_CONFIG} from './config.token';
+
+export const appConfig: AppConfig = {
+ apiUrl: 'https://api.example.com',
+};
+
+bootstrapApplication(App, {
+ providers: [{provide: APP_CONFIG, useValue: appConfig}],
+});
+```
+
+```angular-ts {avoid, header: 'feature-view.ts'}
+// Creating new token with same description
+import {InjectionToken, inject} from '@angular/core';
+import {AppConfig} from './config.token';
+
+const APP_CONFIG = new InjectionToken('app config');
+
+@Component({
+ selector: 'app-feature',
+ template: '
Feature
',
+})
+export class FeatureView {
+ private config = inject(APP_CONFIG); // ERROR: Different token instance!
+}
+```
+
+Even though both tokens have the description `'app config'`, they are different objects. Angular compares tokens by reference, not by description.
+
+**Solution:** Import the same token instance.
+
+```angular-ts {prefer, header: 'feature-view.ts'}
+import {inject} from '@angular/core';
+import {APP_CONFIG, AppConfig} from './config.token';
+
+@Component({
+ selector: 'app-feature',
+ template: '
API: {{config.apiUrl}}
',
+})
+export class FeatureView {
+ protected config = inject(APP_CONFIG); // Works: Same token instance
+}
+```
+
+TIP: Always export tokens from a shared file and import them everywhere they're needed. Never create multiple `InjectionToken` instances with the same description.
+
+#### Trying to inject interfaces
+
+When you define a TypeScript interface, it only exists during compilation for type checking. TypeScript erases all interface definitions when it compiles to JavaScript, so at runtime there's no object for Angular to use as an injection token. If you try to inject an interface type, Angular has nothing to match against the provider configuration.
+
+```angular-ts {avoid, header: 'Can't inject interface'}
+interface UserConfig {
+ name: string;
+ email: string;
+}
+
+@Component({
+ selector: 'app-profile',
+ template: '
Profile
',
+})
+export class UserProfile {
+ // ERROR: Interfaces don't exist at runtime
+ constructor(private config: UserConfig) {}
+}
+```
+
+**Solution:** Use `InjectionToken` for interface types.
+
+```angular-ts {prefer, header: 'Use InjectionToken for interfaces'}
+import {InjectionToken, inject} from '@angular/core';
+
+interface UserConfig {
+ name: string;
+ email: string;
+}
+
+export const USER_CONFIG = new InjectionToken('user configuration');
+
+// Provide the configuration
+bootstrapApplication(App, {
+ providers: [
+ {
+ provide: USER_CONFIG,
+ useValue: {name: 'Alice', email: 'alice@example.com'},
+ },
+ ],
+});
+
+// Inject using the token
+@Component({
+ selector: 'app-profile',
+ template: '
User: {{config.name}}
',
+})
+export class UserProfile {
+ protected config = inject(USER_CONFIG);
+}
+```
+
+The `InjectionToken` exists at runtime and can be used for injection, while the `UserConfig` interface provides type safety during development.
+
+### Circular dependencies
+
+Circular dependencies occur when services inject each other, creating a cycle that Angular cannot resolve. For detailed explanations and code examples, see [NG0200: Circular dependency](errors/NG0200).
+
+**Resolution strategies** (in order of preference):
+
+1. **Restructure** - Extract shared logic to a third service, breaking the cycle
+2. **Use events** - Replace direct dependencies with event-based communication (such as `Subject`)
+3. **Lazy injection** - Use `Injector.get()` to defer one dependency (last resort)
+
+NOTE: Do not use `forwardRef()` for service circular dependencies—it only solves circular imports in standalone component configurations.
+
+## Debugging dependency resolution
+
+### Understanding the resolution process
+
+Angular resolves dependencies by walking up the injector hierarchy. When a `NullInjectorError` occurs, understanding this search order helps you identify where to add the missing provider.
+
+Angular searches in this order:
+
+1. **Element injector** - The current component or directive
+2. **Parent element injectors** - Up the DOM tree through parent components
+3. **Environment injector** - The route or application injector
+4. **NullInjector** - Throws `NullInjectorError` if not found
+
+When you see a `NullInjectorError`, the service isn't provided at any level the component can access. Check that:
+
+- The service has `@Injectable({providedIn: 'root'})`, or
+- The service is in a `providers` array the component can reach
+
+You can modify this search behavior with resolution modifiers like `self`, `skipSelf`, `host`, and `optional`. For complete coverage of resolution rules and modifiers, see the [Hierarchical injectors guide](guide/di/hierarchical-dependency-injection).
+
+### Using Angular DevTools
+
+Angular DevTools includes an injector tree inspector that visualizes the entire injector hierarchy and shows which providers are available at each level. For installation and general usage, see the [Angular DevTools injector documentation](tools/devtools/injectors).
+
+When debugging DI issues, use DevTools to answer these questions:
+
+- **Is the service provided?** Select the component that fails to inject and check if the service appears in the Injector section.
+- **At what level?** Walk up the component tree to find where the service is actually provided (component, route, or application level).
+- **Multiple instances?** If a singleton service appears in multiple component injectors, it's likely provided in component `providers` arrays instead of using `providedIn: 'root'`.
+
+If a service never appears in any injector, verify it has the `@Injectable()` decorator with `providedIn: 'root'` or is listed in a `providers` array.
+
+### Logging and tracing injection
+
+When DevTools isn't enough, use logging to trace injection behavior.
+
+#### Logging service creation
+
+Add console logs to service constructors to see when services are created.
+
+```ts
+import {Injectable} from '@angular/core';
+
+@Injectable({providedIn: 'root'})
+export class UserClient {
+ constructor() {
+ console.log('UserClient created');
+ console.trace(); // Shows call stack
+ }
+
+ getUser() {
+ return {name: 'Alice'};
+ }
+}
+```
+
+When the service is created, you'll see the log message and a stack trace showing where the injection occurred.
+
+**What to look for:**
+
+- How many times is the constructor called? (should be once for singletons)
+- Where in the code is it being injected? (check the stack trace)
+- Is it created at the expected time? (application startup vs lazy)
+
+#### Checking service availability
+
+Use optional injection with logging to determine if a service is available.
+
+```angular-ts
+import {Component, inject} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-debug',
+ template: '
Debug Component
',
+})
+export class DebugView {
+ private userService = inject(UserClient, {optional: true});
+
+ constructor() {
+ if (this.userService) {
+ console.log('UserClient available:', this.userService);
+ } else {
+ console.warn('UserClient NOT available');
+ console.trace(); // Shows where we tried to inject
+ }
+ }
+}
+```
+
+This pattern helps you verify if a service is available without crashing the application.
+
+#### Logging resolution modifiers
+
+Test different resolution strategies with logging.
+
+```angular-ts
+import {Component, inject} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-debug',
+ template: '
Debug Component
',
+ providers: [UserClient],
+})
+export class DebugView {
+ // Try to get local instance
+ private localService = inject(UserClient, {self: true, optional: true});
+
+ // Try to get parent instance
+ private parentService = inject(UserClient, {
+ skipSelf: true,
+ optional: true,
+ });
+
+ constructor() {
+ console.log('Local instance:', this.localService);
+ console.log('Parent instance:', this.parentService);
+ console.log('Same instance?', this.localService === this.parentService);
+ }
+}
+```
+
+This shows you which instances are available at different injector levels.
+
+### Debugging workflow
+
+When DI fails, follow this systematic approach:
+
+**Step 1: Read the error message**
+
+- Identify the error code (NG0200, NG0203, etc.)
+- Read the dependency path
+- Note which token failed
+
+**Step 2: Check the basics**
+
+- Does the service have `@Injectable()`?
+- Is `providedIn` set correctly?
+- Are imports correct?
+- Is the file included in compilation?
+
+**Step 3: Verify injection context**
+
+- Is `inject()` called in a valid context?
+- Check for async issues (await, setTimeout, promises)
+- Verify timing (not after destroy)
+
+**Step 4: Use debugging tools**
+
+- Open Angular DevTools
+- Check injector hierarchy
+- Add console logs to constructors
+- Use optional injection to test availability
+
+**Step 5: Simplify and isolate**
+
+- Remove dependencies one by one
+- Test in a minimal component
+- Check each injector level separately
+- Create a reproduction case
+
+## DI error reference
+
+This section provides detailed information about specific Angular DI error codes you may encounter. Use this as a reference when you see these errors in your console.
+
+### NullInjectorError: No provider for [Service]
+
+**Error code:** None (displayed as `NullInjectorError`)
+
+This error occurs when Angular cannot find a provider for a token in the injector hierarchy. The error message includes a dependency path showing where the injection was attempted.
+
+```
+NullInjectorError: No provider for UserClient!
+ Dependency path: App -> AuthClient -> UserClient
+```
+
+The dependency path shows that `App` injected `AuthClient`, which tried to inject `UserClient`, but no provider was found.
+
+#### Missing @Injectable decorator
+
+The most common cause is forgetting the `@Injectable()` decorator on a service class.
+
+```ts {avoid, header: 'Missing decorator'}
+export class UserClient {
+ getUser() {
+ return {name: 'Alice'};
+ }
+}
+```
+
+Angular requires the `@Injectable()` decorator to generate the metadata needed for dependency injection.
+
+```ts {prefer, header: 'Include @Injectable'}
+import {Injectable} from '@angular/core';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class UserClient {
+ getUser() {
+ return {name: 'Alice'};
+ }
+}
+```
+
+NOTE: Classes with zero-argument constructors can work without `@Injectable()`, but this is not recommended. Always include the decorator for consistency and to avoid issues when adding dependencies later.
+
+#### Missing providedIn configuration
+
+A service may have `@Injectable()` but not specify where it should be provided.
+
+```ts {avoid, header: 'No providedIn specified'}
+import {Injectable} from '@angular/core';
+
+@Injectable()
+export class UserClient {
+ getUser() {
+ return {name: 'Alice'};
+ }
+}
+```
+
+Specify `providedIn: 'root'` to make the service available throughout your application.
+
+```ts {prefer, header: 'Specify providedIn'}
+import {Injectable} from '@angular/core';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class UserClient {
+ getUser() {
+ return {name: 'Alice'};
+ }
+}
+```
+
+The `providedIn: 'root'` configuration makes the service available application-wide and enables tree-shaking (the service is removed from the bundle if never injected).
+
+#### Standalone component missing imports
+
+In Angular v20+ with standalone components, you must explicitly import or provide dependencies in each component.
+
+```angular-ts {avoid, header: 'Missing service import'}
+import {Component, inject} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-profile',
+ template: '
User: {{user().name}}
',
+})
+export class UserProfile {
+ private userService = inject(UserClient); // ERROR: No provider
+ user = this.userService.getUser();
+}
+```
+
+Ensure the service uses `providedIn: 'root'` or add it to the component's `providers` array.
+
+```angular-ts {prefer, header: 'Service uses providedIn: root'}
+import {Component, inject} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-profile',
+ template: '
User: {{user().name}}
',
+})
+export class UserProfile {
+ private userService = inject(UserClient); // Works: providedIn: 'root'
+ user = this.userService.getUser();
+}
+```
+
+#### Debugging with the dependency path
+
+The dependency path in the error message shows the chain of injections that led to the failure.
+
+```
+NullInjectorError: No provider for LoggerStore!
+ Dependency path: App -> DataStore -> ApiClient -> LoggerStore
+```
+
+This path tells you:
+
+1. `App` injected `DataStore`
+2. `DataStore` injected `ApiClient`
+3. `ApiClient` tried to inject `LoggerStore`
+4. No provider for `LoggerStore` was found
+
+Start your investigation at the end of the chain (`LoggerStore`) and verify it has proper configuration.
+
+#### Checking provider availability with optional injection
+
+Use optional injection to check if a provider exists without throwing an error.
+
+```angular-ts
+import {Component, inject} from '@angular/core';
+import {UserClient} from './user-client';
+
+@Component({
+ selector: 'app-debug',
+ template: '
Service available: {{serviceAvailable}}
',
+})
+export class DebugView {
+ private userService = inject(UserClient, {optional: true});
+ serviceAvailable = this.userService !== null;
+}
+```
+
+Optional injection returns `null` if no provider is found, allowing you to handle the absence gracefully.
+
+### NG0203: inject() must be called from an injection context
+
+**Error code:** NG0203
+
+This error occurs when you call `inject()` outside of a valid injection context. Angular requires `inject()` to be called synchronously during class construction or factory execution.
+
+```
+NG0203: inject() must be called from an injection context such as a
+constructor, a factory function, a field initializer, or a function
+used with `runInInjectionContext`.
+```
+
+#### Valid injection contexts
+
+Angular allows `inject()` in these locations:
+
+1. **Class field initializers**
+
+ ```angular-ts
+ import {Component, inject} from '@angular/core';
+ import {UserClient} from './user-client';
+
+ @Component({
+ selector: 'app-profile',
+ template: '
',
+ })
+ export class UserProfile {
+ private userService: UserClient;
+
+ constructor() {
+ this.userService = inject(UserClient); // Valid
+ }
+
+ user = this.userService.getUser();
+ }
+ ```
+
+3. **Provider factory functions**
+
+ ```ts
+ import {inject, InjectionToken} from '@angular/core';
+ import {UserClient} from './user-client';
+
+ export const GREETING = new InjectionToken('greeting', {
+ factory() {
+ const userService = inject(UserClient); // Valid
+ const user = userService.getUser();
+ return `Hello, ${user.name}`;
+ },
+ });
+ ```
+
+4. **Inside runInInjectionContext()**
+
+ ```angular-ts
+ import {Component, inject, Injector} from '@angular/core';
+ import {UserClient} from './user-client';
+
+ @Component({
+ selector: 'app-profile',
+ template: '',
+ })
+ export class UserProfile {
+ private injector = inject(Injector);
+
+ loadUser() {
+ this.injector.runInInjectionContext(() => {
+ const userService = inject(UserClient); // Valid
+ console.log(userService.getUser());
+ });
+ }
+ }
+ ```
+
+Other injection contexts that `inject()` also works in include:
+
+- [provideAppInitializer](api/core/provideAppInitializer)
+- [provideEnvironmentInitializer](api/core/provideEnvironmentInitializer)
+- Functional [route guards](guide/routing/route-guards)
+- Functional [data resolvers](guide/routing/data-resolvers)
+
+#### When this error occurs
+
+This error occurs when:
+
+- Calling `inject()` in lifecycle hooks (`ngOnInit`, `ngAfterViewInit`, etc.)
+- Calling `inject()` after `await` in async functions
+- Calling `inject()` in callbacks (`setTimeout`, `Promise.then()`, etc.)
+- Calling `inject()` outside of class construction phase
+
+See the "Incorrect inject() usage" section for detailed examples and solutions.
+
+#### Solutions and workarounds
+
+**Solution 1:** Capture dependencies in field initializers (most common)
+
+```ts
+private userService = inject(UserClient) // Capture at class level
+```
+
+**Solution 2:** Use `runInInjectionContext()` for callbacks
+
+```ts
+private injector = inject(Injector)
+
+someCallback() {
+ this.injector.runInInjectionContext(() => {
+ const service = inject(MyClient)
+ })
+}
+```
+
+**Solution 3:** Pass dependencies as parameters instead of injecting them
+
+```ts
+// Instead of injecting inside a callback
+setTimeout(() => {
+ const service = inject(MyClient) // ERROR
+}, 1000)
+
+// Capture first, then use
+private service = inject(MyClient)
+
+setTimeout(() => {
+ this.service.doSomething() // Use captured reference
+}, 1000)
+```
+
+### NG0200: Circular dependency detected
+
+**Error code:** NG0200
+
+This error occurs when two or more services depend on each other, creating a circular dependency that Angular cannot resolve.
+
+```
+NG0200: Circular dependency in DI detected for AuthClient
+ Dependency path: AuthClient -> UserClient -> AuthClient
+```
+
+The dependency path shows the cycle: `AuthClient` depends on `UserClient`, which depends back on `AuthClient`.
+
+#### Understanding the error
+
+Angular creates service instances by calling their constructors and injecting dependencies. When services depend on each other circularly, Angular cannot determine which to create first.
+
+#### Common causes
+
+- Direct circular dependency (Service A → Service B → Service A)
+- Indirect circular dependency (Service A → Service B → Service C → Service A)
+- Import cycles in module files that also have service dependencies
+
+#### Resolution strategies
+
+See the "Circular dependencies" section for detailed examples and solutions:
+
+1. **Restructure** - Extract shared logic to a third service (recommended)
+2. **Use events** - Replace direct dependencies with event-based communication
+3. **Lazy injection** - Use `Injector.get()` to defer one dependency (last resort)
+
+Do NOT use `forwardRef()` for service circular dependencies. It only solves circular imports in component configurations.
+
+### Other DI error codes
+
+For detailed explanations and solutions for these errors, see the [Angular error reference](errors):
+
+| Error Code | Description |
+| ----------------------- | ------------------------------------------------------------------------------------------ |
+| [NG0204](errors/NG0204) | Can't resolve all parameters - missing `@Injectable()` decorator |
+| [NG0205](errors/NG0205) | Injector already destroyed - accessing services after component destruction |
+| [NG0207](errors/NG0207) | EnvironmentProviders in wrong context - using `provideHttpClient()` in component providers |
+
+## Next steps
+
+When you encounter DI errors, remember to:
+
+1. Read the error message and dependency path carefully
+2. Verify basic configuration (decorators, `providedIn`, imports)
+3. Check injection context and timing
+4. Use DevTools and logging to investigate
+5. Simplify and isolate the problem
+
+For a deeper understanding of specific topics on dependency injection, check out:
+
+- [Understanding dependency injection](guide/di) - Core DI concepts and patterns
+- [Hierarchical dependency injection](guide/di/hierarchical-dependency-injection) - How the injector hierarchy works
+- [Testing with dependency injection](guide/testing) - Using TestBed and mocking dependencies
diff --git a/adev-ja/src/content/guide/di/defining-dependency-providers.md b/adev-ja/src/content/guide/di/defining-dependency-providers.md
index f685b05ef3..84d4684f46 100644
--- a/adev-ja/src/content/guide/di/defining-dependency-providers.md
+++ b/adev-ja/src/content/guide/di/defining-dependency-providers.md
@@ -66,7 +66,7 @@ export const APP_CONFIG = new InjectionToken('app.config', {
selector: 'app-header',
template: `
Version: {{ config.version }}
`,
})
-export class HeaderComponent {
+export class Header {
config = inject(APP_CONFIG); // Automatically available
}
```
@@ -167,7 +167,7 @@ export class LocalDataStore {
providers: [LocalDataStore],
template: `...`,
})
-export class ExampleComponent {
+export class Example {
dataStore = inject(LocalDataStore);
}
```
@@ -191,7 +191,7 @@ export class DataStore {
providers: [DataStore],
template: `...`,
})
-export class IsolatedComponent {
+export class Isolated {
dataStore = inject(DataStore); // Component-specific instance
}
```
@@ -235,14 +235,14 @@ Think of Angular's dependency injection system as a hash map or dictionary. Each
When manually providing dependencies, you typically see this shorthand syntax:
```angular-ts
-import { Component } from '@angular/core';
-import { LocalService } from './local-service';
+import {Component} from '@angular/core';
+import {LocalService} from './local-service';
@Component({
selector: 'app-example',
- providers: [LocalService] // Service without providedIn
+ providers: [LocalService], // Service without providedIn
})
-export class ExampleComponent { }
+export class Example {}
```
This is actually a shorthand for a more detailed provider configuration:
@@ -282,16 +282,16 @@ Provider identifiers allow Angular's dependency injection (DI) system to retriev
Class name use the imported class directly as the identifier:
```angular-ts
-import { Component } from '@angular/core';
-import { LocalService } from './local-service';
+import {Component} from '@angular/core';
+import {LocalService} from './local-service';
@Component({
selector: 'app-example',
- providers: [
- { provide: LocalService, useClass: LocalService }
- ]
+ providers: [{provide: LocalService, useClass: LocalService}],
})
-export class ExampleComponent { /* ... */ }
+export class Example {
+ /* ... */
+}
```
The class serves as both the identifier and the implementation, which is why Angular provides the shorthand `providers: [LocalService]`.
@@ -313,17 +313,15 @@ NOTE: The string `'DataService'` is a description used purely for debugging purp
Use the token in your provider configuration:
```angular-ts
-import { Component, inject } from '@angular/core';
-import { LocalDataService } from './local-data-service';
-import { DATA_SERVICE_TOKEN } from './tokens';
+import {Component, inject} from '@angular/core';
+import {LocalDataService} from './local-data-service';
+import {DATA_SERVICE_TOKEN} from './tokens';
@Component({
selector: 'app-example',
- providers: [
- { provide: DATA_SERVICE_TOKEN, useClass: LocalDataService }
- ]
+ providers: [{provide: DATA_SERVICE_TOKEN, useClass: LocalDataService}],
})
-export class ExampleComponent {
+export class Example {
private dataService = inject(DATA_SERVICE_TOKEN);
}
```
@@ -344,7 +342,7 @@ interface DataService {
{provide: DataService, useClass: LocalDataService}, // Error!
],
})
-export class ExampleComponent {
+export class Example {
private dataService = inject(DataService); // Error!
}
@@ -354,7 +352,7 @@ export const DATA_SERVICE_TOKEN = new InjectionToken('DataService')
@Component({
providers: [{provide: DATA_SERVICE_TOKEN, useClass: LocalDataService}],
})
-export class ExampleComponent {
+export class Example {
private dataService = inject(DATA_SERVICE_TOKEN); // Works!
}
```
@@ -428,7 +426,7 @@ export class EvenBetterLogger extends Logger {
{provide: Logger, useClass: EvenBetterLogger},
],
})
-export class ExampleComponent {
+export class Example {
private logger = inject(Logger); // Gets EvenBetterLogger instance
}
```
@@ -485,7 +483,7 @@ bootstrapApplication(AppComponent, {
selector: 'app-header',
template: `
{{ title }}
`,
})
-export class HeaderComponent {
+export class Header {
private config = inject(APP_CONFIG);
title = this.config.appTitle;
}
@@ -575,7 +573,7 @@ export const apiClientProvider = {
selector: 'app-dashboard',
providers: [apiClientProvider],
})
-export class DashboardComponent {
+export class Dashboard {
private apiClient = inject(ApiClient);
}
```
@@ -628,7 +626,7 @@ Use application-level providers in `bootstrapApplication` when:
```ts
// main.ts
-bootstrapApplication(AppComponent, {
+bootstrapApplication(App, {
providers: [
{provide: API_BASE_URL, useValue: 'https://api.example.com'},
{provide: INTERCEPTOR_TOKEN, useClass: AuthInterceptor, multi: true},
@@ -672,20 +670,20 @@ Use component or directive providers when:
@Component({
selector: 'app-advanced-form',
providers: [
- FormValidationService, // Each form gets its own validator
- { provide: FORM_CONFIG, useValue: { strictMode: true } }
- ]
+ FormValidationService, // Each form gets its own validator
+ {provide: FORM_CONFIG, useValue: {strictMode: true}},
+ ],
})
-export class AdvancedFormComponent { }
+export class AdvancedForm {}
// Modal component with isolated state management
@Component({
selector: 'app-modal',
providers: [
- ModalStateService // Each modal manages its own state
- ]
+ ModalStateService, // Each modal manages its own state
+ ],
})
-export class ModalComponent { }
+export class Modal {}
```
**Benefits:**
@@ -771,7 +769,7 @@ export function provideAnalytics(config: AnalyticsConfig): Provider[] {
// Usage in consumer app
// main.ts
-bootstrapApplication(AppComponent, {
+bootstrapApplication(App, {
providers: [
provideAnalytics({
trackingId: 'GA-12345',
@@ -881,7 +879,7 @@ export function withRetry(config: RetryConfig): HttpFeature {
}
// Consumer usage with multiple features
-bootstrapApplication(AppComponent, {
+bootstrapApplication(App, {
providers: [
provideHttpClient(
{baseUrl: 'https://api.example.com'},
diff --git a/adev-ja/src/content/guide/di/dependency-injection-context.md b/adev-ja/src/content/guide/di/dependency-injection-context.md
index d986c13139..e23ba8eb6c 100644
--- a/adev-ja/src/content/guide/di/dependency-injection-context.md
+++ b/adev-ja/src/content/guide/di/dependency-injection-context.md
@@ -31,7 +31,7 @@ const canActivateTeam: CanActivateFn = (
};
```
-## 注入コンテキスト内で実行する
+## 注入コンテキスト内で実行する {#run-within-an-injection-context}
すでに注入コンテキスト内にいない状態で、特定の関数を注入コンテキスト内で実行したい場合は、`runInInjectionContext` を使用できます。
これには、たとえば `EnvironmentInjector` のような特定のインジェクターへのアクセスが必要です。
@@ -53,7 +53,7 @@ export class HeroService {
[`inject`](/api/core/inject) は、インジェクターが要求されたトークンを解決できる場合にのみインスタンスを返します。
-## コンテキストのアサート
+## コンテキストのアサート {#asserts-the-context}
Angularは、現在のコンテキストが注入コンテキストであることをアサートし、そうでない場合は明確なエラーをスローするための `assertInInjectionContext` ヘルパー関数を提供します。呼び出し元の関数への参照を渡すと、エラーメッセージが正しいAPIエントリーポイントを指し示すようになります。これにより、デフォルトの汎用的な注入エラーよりも明確で実用的なメッセージが生成されます。
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 f9a09ce173..75e92df648 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
@@ -68,7 +68,7 @@ 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);
+bootstrapApplication(App, appConfig);
```
The `bootstrapApplication()` method creates a child injector of the platform injector which is configured by the `ApplicationConfig` instance.
@@ -106,7 +106,7 @@ All requests forward up to the root injector, whether you configured it with the
If you configure an app-wide provider in the `ApplicationConfig` of `bootstrapApplication`, it overrides one configured for `root` in the `@Injectable()` metadata.
You can do this to configure a non-default provider of a service that is shared with multiple applications.
-Here is an example of the case where the component router configuration includes a non-default [location strategy](guide/routing#location-strategy) by listing its provider in the `providers` list of the `ApplicationConfig`.
+Here is an example of the case where the component router configuration includes a non-default [location strategy](guide/routing/common-router-tasks#locationstrategy-and-browser-url-styles) by listing its provider in the `providers` list of the `ApplicationConfig`.
```ts
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}];
@@ -193,8 +193,8 @@ 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 {
+```ts {header:"src/app/optional/optional.ts"}
+export class Optional {
public optional? = inject(OptionalService, {optional: true});
}
```
@@ -206,15 +206,15 @@ Use `self` so that Angular will only look at the `ElementInjector` for the curre
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`.
-For example, in the following `SelfNoDataComponent`, notice the injected `LeafService` as a property.
+For example, in the following `SelfNoData`, notice the injected `LeafService` as a property.
-```ts {header: 'self-no-data.component.ts', highlight: [7]}
+```ts {header: 'self-no-data.ts', highlight: [7]}
@Component({
selector: 'app-self-no-data',
- templateUrl: './self-no-data.component.html',
- styleUrls: ['./self-no-data.component.css'],
+ templateUrl: './self-no-data.html',
+ styleUrls: ['./self-no-data.css'],
})
-export class SelfNoDataComponent {
+export class SelfNoData {
public leaf = inject(LeafService, {optional: true, self: true});
}
```
@@ -224,14 +224,14 @@ In this example, there is a parent provider and injecting the service will retur
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 🌷.
-```ts {header:"src/app/self/self.component.ts"}
+```ts {header:"src/app/self/self.ts"}
@Component({
selector: 'app-self',
- templateUrl: './self.component.html',
- styleUrls: ['./self.component.css'],
+ templateUrl: './self.html',
+ styleUrls: ['./self.css'],
providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}],
})
-export class SelfComponent {
+export class Self {
constructor(@Self() public flower: FlowerService) {}
}
```
@@ -253,15 +253,15 @@ export class LeafService {
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:"skipself.component.ts" highlight:[[6],[10]]}
+```ts {header:"skipself.ts" highlight:[[6],[10]]}
@Component({
selector: 'app-skipself',
- templateUrl: './skipself.component.html',
- styleUrls: ['./skipself.component.css'],
+ templateUrl: './skipself.html',
+ styleUrls: ['./skipself.css'],
// Angular would ignore this LeafService instance
providers: [{provide: LeafService, useValue: {emoji: '🍁'}}],
})
-export class SkipselfComponent {
+export class Skipself {
// Use skipSelf as inject option
public leaf = inject(LeafService, {skipSelf: true});
}
@@ -291,21 +291,21 @@ class Person {
Even if there is a service instance further up the tree, Angular won't continue looking.
Use `host` as follows:
-```ts {header:"host.component.ts" highlight:[[6],[9]]}
+```ts {header:"host.ts" highlight:[[6],[9]]}
@Component({
selector: 'app-host',
- templateUrl: './host.component.html',
- styleUrls: ['./host.component.css'],
+ templateUrl: './host.html',
+ styleUrls: ['./host.css'],
// provide the service
providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}],
})
-export class HostComponent {
+export class Host {
// 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 `Host` has the `host` option , no matter what the parent of `Host` might have as a `flower.emoji` value, the `Host` will use tulip 🌷.
### Modifiers with constructor injection
@@ -313,8 +313,8 @@ Similarly as presented before, the behavior of constructor injection can be modi
Import each of them from `@angular/core` and use each in the component class constructor when you inject your service.
-```ts {header:"self-no-data.component.ts" highlight:[2]}
-export class SelfNoDataComponent {
+```ts {header:"self-no-data.ts" highlight:[2]}
+export class SelfNoData {
constructor(@Self() @Optional() public leaf?: LeafService) {}
}
```
@@ -390,22 +390,22 @@ export class FlowerService {
}
```
-Consider an application with only an `AppComponent` and a `ChildComponent`.
+Consider an application with only an `App` and a `Child`.
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>
-
+
<#VIEW>
#VIEW>
@@ -421,7 +421,7 @@ Knowledge of this structure can inform how you provide and inject your services,
Now, consider that `` injects the `FlowerService`:
```typescript
-export class AppComponent {
+export class App {
flower = inject(FlowerService);
}
```
@@ -434,7 +434,7 @@ Add a binding to the `` template to visualize the result:
The output in the view would be:
-```shell
+```text {hideCopy}
Emoji from FlowerService: 🌺
```
@@ -474,17 +474,17 @@ In the example case, the constraints are:
### Using the `providers` array
-Now, in the `ChildComponent` class, add a provider for `FlowerService` to demonstrate more complex resolution rules in the upcoming sections:
+Now, in the `Child` class, add a provider for `FlowerService` to demonstrate more complex resolution rules in the upcoming sections:
```ts
@Component({
selector: 'app-child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.css'],
+ templateUrl: './child.html',
+ styleUrls: ['./child.css'],
// use the providers array to provide a service
providers: [{provide: FlowerService, useValue: {emoji: '🌻'}}],
})
-export class ChildComponent {
+export class Child {
// inject the service
flower = inject(FlowerService);
}
@@ -493,15 +493,15 @@ export class ChildComponent {
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.
+The next step is to add a binding to the `Child` 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:
+To render the new values, add `` to the bottom of the `App` template so the view also displays the sunflower:
-```shell
+```text {hideCopy}
Child Component
Emoji from FlowerService: 🌻
```
@@ -555,10 +555,10 @@ export class AnimalService {
}
```
-Following the same pattern as with the `FlowerService`, inject the `AnimalService` in the `AppComponent` class:
+Following the same pattern as with the `FlowerService`, inject the `AnimalService` in the `App` class:
```ts
-export class AppComponent {
+export class App {
public flower = inject(FlowerService);
public animal = inject(AnimalService);
}
@@ -572,37 +572,36 @@ Here, it has a value of dog 🐶.
```typescript
@Component({
selector: 'app-child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.css'],
+ templateUrl: './child.html',
+ styleUrls: ['./child.css'],
// provide services
providers: [{provide: FlowerService, useValue: {emoji: '🌻'}}],
viewProviders: [{provide: AnimalService, useValue: {emoji: '🐶'}}],
})
-export class ChildComponent {
+export class Child {
// 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:
+Add bindings to the `Child` and the `App` templates.
+In the `Child` template, add the following binding:
```html
Emoji from AnimalService: {{animal.emoji}}
```
-Additionally, add the same to the `AppComponent` template:
+Additionally, add the same to the `App` template:
```html
Emoji from AnimalService: {{animal.emoji}}
-s
```
Now you should see both values in the browser:
-```shell
-AppComponent
+```text {hideCopy}
+App
Emoji from AnimalService: 🐳
Child Component
@@ -637,35 +636,35 @@ It doesn't need to continue searching the `ElementInjector` tree, nor does it ne
The `viewProviders` field is conceptually similar to `providers`, but there is one notable difference.
Configured providers in `viewProviders` are not visible to projected content that ends up as a logical children of the component.
-To see the difference between using `providers` and `viewProviders`, add another component to the example and call it `InspectorComponent`.
-`InspectorComponent` will be a child of the `ChildComponent`.
-In `inspector.component.ts`, inject the `FlowerService` and `AnimalService` during property initialization:
+To see the difference between using `providers` and `viewProviders`, add another component to the example and call it `Inspector`.
+`Inspector` will be a child of the `Child`.
+In `inspector.ts`, inject the `FlowerService` and `AnimalService` during property initialization:
```typescript
-export class InspectorComponent {
+export class Inspector {
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:
+Next, in `inspector.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.
+Remember to add the `Inspector` to the `Child` `imports` array.
```ts
@Component({
...
- imports: [InspectorComponent]
+ imports: [Inspector]
})
```
-Next, add the following to `child.component.html`:
+Next, add the following to `child.html`:
```html
...
@@ -679,9 +678,9 @@ Next, add the following to `child.component.html`:
```
-`` allows you to project content, and `` inside the `ChildComponent` template makes the `InspectorComponent` a child component of `ChildComponent`.
+`` allows you to project content, and `` inside the `Child` template makes the `Inspector` a child component of `Child`.
-Next, add the following to `app.component.html` to take advantage of content projection.
+Next, add the following to `app.html` to take advantage of content projection.
```html
@@ -691,7 +690,7 @@ Next, add the following to `app.component.html` to take advantage of content pro
The browser now renders the following, omitting the previous examples for brevity:
-```shell
+```text {hideCopy}
...
Content projection
@@ -703,10 +702,10 @@ 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.
+Remember that the dog emoji 🐶 is declared inside the `<#VIEW>` of `Child` 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 `Inspector` is an actual child component of `Child`, `Inspector` 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:
@@ -751,7 +750,7 @@ Visibility decorators influence where the search for the injection token begins
To do this, place visibility configuration at the point of injection, that is, when invoking `inject()`, rather than at a point of declaration.
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`:
+This invocation is a property initializer the `` as shown in `child.ts`:
```typescript
flower = inject(FlowerService, {skipSelf: true});
@@ -762,7 +761,7 @@ Instead, the injector starts looking for the `FlowerService` at the `ElementInje
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:
-```shell
+```text {hideCopy}
Emoji from FlowerService: 🌺
```
@@ -847,7 +846,7 @@ With `skipSelf` in the ``, the injector begins its search for the `An
### `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.
-The `ChildComponent` configures the `viewProviders` so that the dog emoji is provided as `AnimalService` value.
+The `Child` configures the `viewProviders` so that the dog emoji is provided as `AnimalService` value.
You can also see `host` the `inject()`:
```typescript
@@ -858,7 +857,7 @@ You can also see `host` the `inject()`:
{ provide: AnimalService, useValue: { emoji: '🐶' } },
]
})
-export class ChildComponent {
+export class Child {
animal = inject(AnimalService, { host: true })
}
```
@@ -879,24 +878,24 @@ export class ChildComponent {
```
-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.ts` `@Component()` metadata:
```typescript
@Component({
selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: [ './app.component.css' ],
+ templateUrl: './app.html',
+ styleUrls: [ './app.css' ],
viewProviders: [
{ provide: AnimalService, useValue: { emoji: '🦔' } },
],
})
```
-Next, add `skipSelf` along with `host` to the `inject()` for the `AnimalService` injection in `child.component.ts`.
+Next, add `skipSelf` along with `host` to the `inject()` for the `AnimalService` injection in `child.ts`.
Here are `host` and `skipSelf` in the `animal` property initialization:
```typescript
-export class ChildComponent {
+export class Child {
animal = inject(AnimalService, {host: true, skipSelf: true});
}
```
@@ -908,7 +907,7 @@ export class ChildComponent {
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`
In the logical tree, you can see that the `FlowerService` is visible in ``, not its `<#VIEW>`.
-However, the `AnimalService`, which is provided in the `AppComponent` `viewProviders` array, is visible.
+However, the `AnimalService`, which is provided in the `App` `viewProviders` array, is visible.
The logical tree representation shows why this is:
@@ -940,34 +939,34 @@ The ability to configure one or more providers at different levels opens up usef
### Scenario: service isolation
Architectural reasons may lead you to restrict access to a service to the application domain where it belongs.
-For example, consider we build a `VillainsListComponent` that displays a list of villains.
+For example, consider we build a `VillainsList` that displays a list of villains.
It gets those villains from a `VillainsService`.
If you provide `VillainsService` in the root `AppModule`, it will make `VillainsService` visible everywhere in the application.
If you later modify the `VillainsService`, you could break something in other components that started depending this service by accident.
-Instead, you should provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:
+Instead, you should provide the `VillainsService` in the `providers` metadata of the `VillainsList` like this:
```typescript
@Component({
selector: 'app-villains-list',
- templateUrl: './villains-list.component.html',
+ templateUrl: './villains-list.html',
providers: [VillainsService],
})
-export class VillainsListComponent {}
+export class VillainsList {}
```
-By providing `VillainsService` in the `VillainsListComponent` metadata and nowhere else, the service becomes available only in the `VillainsListComponent` and its subcomponent tree.
+By providing `VillainsService` in the `VillainsList` metadata and nowhere else, the service becomes available only in the `VillainsList` and its subcomponent tree.
-`VillainService` is a singleton with respect to `VillainsListComponent` because that is where it is declared.
-As long as `VillainsListComponent` does not get destroyed it will be the same instance of `VillainService` but if there are multiple instances of `VillainsListComponent`, then each instance of `VillainsListComponent` will have its own instance of `VillainService`.
+`VillainsService` is a singleton with respect to `VillainsList` because that is where it is declared.
+As long as `VillainsList` does not get destroyed it will be the same instance of `VillainsService` but if there are multiple instances of `VillainsList`, then each instance of `VillainsList` will have its own instance of `VillainsService`.
### Scenario: multiple edit sessions
Many applications allow users to work on several open tasks at the same time.
For example, in a tax preparation application, the preparer could be working on several tax returns, switching from one to the other throughout the day.
-To demonstrate that scenario, imagine a `HeroListComponent` that displays a list of super heroes.
+To demonstrate that scenario, imagine a `HeroList` that displays a list of super heroes.
To open a hero's tax return, the preparer clicks on a hero name, which opens a component for editing that return.
Each selected hero tax return opens in its own component and multiple returns can be open at the same time.
@@ -978,7 +977,7 @@ Each tax return component has the following characteristics:
- 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.
+Suppose that the `HeroTaxReturn` had logic to manage and restore changes.
That would be a straightforward task for a hero tax return.
In the real world, with a rich tax return data model, the change management would be tricky.
You could delegate that management to a helper service, as this example does.
@@ -1018,7 +1017,7 @@ export class HeroTaxReturnService {
}
```
-Here is the `HeroTaxReturnComponent` that makes use of `HeroTaxReturnService`.
+Here is the `HeroTaxReturn` that makes use of `HeroTaxReturnService`.
```typescript
import {Component, input, output} from '@angular/core';
@@ -1027,11 +1026,11 @@ 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'],
+ templateUrl: './hero-tax-return.html',
+ styleUrls: ['./hero-tax-return.css'],
providers: [HeroTaxReturnService],
})
-export class HeroTaxReturnComponent {
+export class HeroTaxReturn {
message = '';
close = output();
@@ -1079,13 +1078,13 @@ The component also asks the service to save and restore this tax return.
This won't work if the service is an application-wide singleton.
Every component would share the same service instance, and each component would overwrite the tax return that belonged to another hero.
-To prevent this, configure the component-level injector of `HeroTaxReturnComponent` to provide the service, using the `providers` property in the component metadata.
+To prevent this, configure the component-level injector of `HeroTaxReturn` to provide the service, using the `providers` property in the component metadata.
```typescript
providers: [HeroTaxReturnService];
```
-The `HeroTaxReturnComponent` has its own provider of the `HeroTaxReturnService`.
+The `HeroTaxReturn` has its own provider of the `HeroTaxReturnService`.
Recall that every component _instance_ has its own injector.
Providing the service at the component level ensures that _every_ instance of the component gets a private instance of the service. This makes sure that no tax return gets overwritten.
@@ -1170,5 +1169,5 @@ style RootInjector fill:#BDD7EE,color:#000
## More on dependency injection
-
+
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 78499ddaac..afcaff2077 100644
--- a/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md
+++ b/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md
@@ -68,7 +68,7 @@ export class ItemService {
Angularが `main.ts` の次の内容でアプリケーションをブートストラップする方法を検討してください。
```ts
-bootstrapApplication(AppComponent, appConfig);
+bootstrapApplication(App, appConfig);
```
`bootstrapApplication()` メソッドは、 `ApplicationConfig` インスタンスによって構成されたプラットフォームインジェクターの子インジェクターを作成します。
@@ -106,7 +106,7 @@ stateDiagram-v2
`bootstrapApplication()` の `ApplicationConfig` でアプリケーション全体のプロバイダーを構成すると、 `@Injectable()` メタデータの `root` で構成されたプロバイダーがオーバーライドされます。
これは、複数のアプリケーションで共有されるサービスのデフォルト以外のプロバイダーを構成する場合に行うことができます。
-コンポーネントルーターの構成にデフォルト以外の [ロケーション戦略](guide/routing#location-strategy) が含まれている場合、 `ApplicationConfig` の `providers` リストにそのプロバイダーをリストすることによって、その例を示します。
+コンポーネントルーターの構成にデフォルト以外の [ロケーション戦略](guide/routing/common-router-tasks#locationstrategy-and-browser-url-styles) が含まれている場合、 `ApplicationConfig` の `providers` リストにそのプロバイダーをリストすることによって、その例を示します。
```ts
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}];
@@ -193,8 +193,8 @@ Angularの解決動作は、`optional`、`self`、`skipSelf`、および `host`
そのため、実行時に解決できない場合、Angularはサービスをエラーをスローするのではなく、 `null` として解決します。
次の例では、サービス `OptionalService` はサービス `ApplicationConfig`や`@NgModule()`、コンポーネントクラスで提供されていないため、アプリケーションのどこにも使用できません。
-```ts {header:"src/app/optional/optional.component.ts"}
-export class OptionalComponent {
+```ts {header:"src/app/optional/optional.ts"}
+export class Optional {
public optional? = inject(OptionalService, {optional: true});
}
```
@@ -206,15 +206,15 @@ export class OptionalComponent {
`self` の適切なユースケースは、サービスを注入するが、現在のホスト要素で使用可能な場合のみにすることです。
このような状況でエラーを回避するには、`self` を `optional` と組み合わせます。
-たとえば、次の `SelfNoDataComponent` では、プロパティとして注入された `LeafService` に注目してください。
+たとえば、次の `SelfNoData` では、プロパティとして注入された `LeafService` に注目してください。
-```ts {header: 'self-no-data.component.ts', highlight: [7]}
+```ts {header: 'self-no-data.ts', highlight: [7]}
@Component({
selector: 'app-self-no-data',
- templateUrl: './self-no-data.component.html',
- styleUrls: ['./self-no-data.component.css'],
+ templateUrl: './self-no-data.html',
+ styleUrls: ['./self-no-data.css'],
})
-export class SelfNoDataComponent {
+export class SelfNoData {
public leaf = inject(LeafService, {optional: true, self: true});
}
```
@@ -224,14 +224,14 @@ export class SelfNoDataComponent {
別の例では、 `FlowerService` のプロバイダーを備えたコンポーネントクラスを示しています。
この場合、インジェクターは現在の `ElementInjector` より先を見ずに、 `FlowerService` を見つけて、チューリップ 🌷 を返します。
-```ts {header:"src/app/self/self.component.ts"}
+```ts {header:"src/app/self/self.ts"}
@Component({
selector: 'app-self',
- templateUrl: './self.component.html',
- styleUrls: ['./self.component.css'],
+ templateUrl: './self.html',
+ styleUrls: ['./self.css'],
providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}],
})
-export class SelfComponent {
+export class Self {
constructor(@Self() public flower: FlowerService) {}
}
```
@@ -253,15 +253,15 @@ export class LeafService {
子コンポーネントに、異なる値、カエデの葉 🍁 が含まれていると想像してください。ただし、親の値を使用したいとします。
これが `skipSelf` を使用する場合です。
-```ts {header:"skipself.component.ts" highlight:[[6],[10]]}
+```ts {header:"skipself.ts" highlight:[[6],[10]]}
@Component({
selector: 'app-skipself',
- templateUrl: './skipself.component.html',
- styleUrls: ['./skipself.component.css'],
+ templateUrl: './skipself.html',
+ styleUrls: ['./skipself.css'],
// Angular はこの LeafService インスタンスを無視します
providers: [{provide: LeafService, useValue: {emoji: '🍁'}}],
})
-export class SkipselfComponent {
+export class Skipself {
// Use skipSelf as inject option
public leaf = inject(LeafService, {skipSelf: true});
}
@@ -291,21 +291,21 @@ class Person {
ツリーのさらに上にサービスインスタンスがある場合でも、Angularは検索を続けません。
`host` を次のように使用します。
-```ts {header:"host.component.ts" highlight:[[6],[9]]}
+```ts {header:"host.ts" highlight:[[6],[9]]}
@Component({
selector: 'app-host',
- templateUrl: './host.component.html',
- styleUrls: ['./host.component.css'],
+ templateUrl: './host.html',
+ styleUrls: ['./host.css'],
// provide the service
providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}],
})
-export class HostComponent {
+export class Host {
// use host when injecting the service
flower = inject(FlowerService, {host: true, optional: true});
}
```
-`HostComponent`に`host`オプションがあるため、`HostComponent`の親が`flower.emoji`にどのような値を持っていても、`HostComponent`はチューリップ🌷を使用します。
+`Host`に`host`オプションがあるため、`Host`の親が`flower.emoji`にどのような値を持っていても、`Host`はチューリップ🌷を使用します。
### コンストラクター注入での修飾子 {#modifiers-with-constructor-injection}
@@ -313,8 +313,8 @@ export class HostComponent {
`@angular/core` からそれぞれをインポートし、サービスを注入するときにコンポーネントクラスのコンストラクターでそれぞれを使用します。
-```ts {header:"self-no-data.component.ts" highlight:[2]}
-export class SelfNoDataComponent {
+```ts {header:"self-no-data.ts" highlight:[2]}
+export class SelfNoData {
constructor(@Self() @Optional() public leaf?: LeafService) {}
}
```
@@ -390,22 +390,22 @@ export class FlowerService {
}
```
-`AppComponent` と `ChildComponent` のみが含まれるアプリケーションを検討してください。
+`App` と `Child` のみが含まれるアプリケーションを検討してください。
最も基本的なレンダリングされたビューは、次のようなネストされたHTML要素のように見えます。
```html
-
-
+
+
```
ただし、裏側では、Angularはインジェクションリクエストを解決するときに、次のような論理ビュー表現を使用します。
```html
-
+
<#VIEW>
-
+
<#VIEW>
#VIEW>
@@ -421,7 +421,7 @@ export class FlowerService {
次に、 `` が `FlowerService` を注入しているとします。
```typescript
-export class AppComponent {
+export class App {
flower = inject(FlowerService);
}
```
@@ -434,7 +434,7 @@ export class AppComponent {
ビューに出力されるのは次のとおりです。
-```shell
+```text {hideCopy}
Emoji from FlowerService: 🌺
```
@@ -474,17 +474,17 @@ Emoji from FlowerService: 🌺
### `providers` 配列を使用する {#using-the-providers-array}
-次に、 `ChildComponent` クラスで、今後のセクションでより複雑な解決ルールを説明するために、 `FlowerService` のプロバイダーを追加します。
+次に、 `Child` クラスで、今後のセクションでより複雑な解決ルールを説明するために、 `FlowerService` のプロバイダーを追加します。
```ts
@Component({
selector: 'app-child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.css'],
+ templateUrl: './child.html',
+ styleUrls: ['./child.css'],
// use the providers array to provide a service
providers: [{provide: FlowerService, useValue: {emoji: '🌻'}}],
})
-export class ChildComponent {
+export class Child {
// inject the service
flower = inject(FlowerService);
}
@@ -493,15 +493,15 @@ export class ChildComponent {
`FlowerService` が `@Component()` デコレーターで提供されるようになったため、 `` がサービスを要求すると、インジェクターは `` の `ElementInjector` ほど遠くまでしか見なくてもよくなります。
インジェクターは、インジェクターツリーをさらに検索する必要はありません。
-次のステップは、 `ChildComponent` テンプレートにバインディングを追加することです。
+次のステップは、 `Child` テンプレートにバインディングを追加することです。
```html
```
-`InspectorComponent` を `ChildComponent` の `imports` 配列に追加することを忘れないでください。
+`Inspector` を `Child` の `imports` 配列に追加することを忘れないでください。
```ts
@Component({
...
- imports: [InspectorComponent]
+ imports: [Inspector]
})
```
-次に、 `child.component.html` に次を追加します。
+次に、 `child.html` に次を追加します。
```html
...
@@ -679,9 +678,9 @@ export class InspectorComponent {
```
-`` を使用するとコンテンツを投影でき、 `ChildComponent` テンプレート内の `` は、 `InspectorComponent` を `ChildComponent` の子コンポーネントにします。
+`` を使用するとコンテンツを投影でき、 `Child` テンプレート内の `` は、 `Inspector` を `Child` の子コンポーネントにします。
-次に、コンテンツ投影を活用するために、 `app.component.html` に次を追加します。
+次に、コンテンツ投影を活用するために、 `app.html` に次を追加します。
```html
@@ -691,7 +690,7 @@ export class InspectorComponent {
これで、ブラウザには、以前の例は省略して、次のものがレンダリングされます。
-```shell
+```text {hideCopy}
...
Content projection
@@ -703,10 +702,10 @@ Emoji from AnimalService: 🐶
```
これらの4つのバインディングは、 `providers` と `viewProviders` の違いを示しています。
-犬の絵文字 🐶 は、 `ChildComponent` の `<#VIEW>` 内に宣言され、投影されたコンテンツには可視ではないことを覚えておいてください。
+犬の絵文字 🐶 は、 `Child` の `<#VIEW>` 内に宣言され、投影されたコンテンツには可視ではないことを覚えておいてください。
代わりに、投影されたコンテンツには、クジラ 🐳 が表示されます。
-ただし、次の出力セクションでは `InspectorComponent` は `ChildComponent` の実際の子コンポーネントです。そして `InspectorComponent` は `<#VIEW>` の内側にあるため、 `AnimalService` を要求すると、犬 🐶 が表示されます。
+ただし、次の出力セクションでは `Inspector` は `Child` の実際の子コンポーネントです。そして `Inspector` は `<#VIEW>` の内側にあるため、 `AnimalService` を要求すると、犬 🐶 が表示されます。
論理ツリー内の `AnimalService` は、次のようになります。
@@ -751,7 +750,7 @@ Emoji from AnimalService: 🐶
これを行うには、宣言のポイントではなく、注入のポイント、つまり `inject()` を呼び出すときに可視性構成を配置します。
インジェクターが `FlowerService` の検索を開始する場所を変更するには、`FlowerService` が注入される `` の `inject()` 呼び出しに `skipSelf` を追加します。
-この呼び出しは、`child.component.ts` に示すように、`` のプロパティ初期化子です。
+この呼び出しは、`child.ts` に示すように、`` のプロパティ初期化子です。
```typescript
flower = inject(FlowerService, {skipSelf: true});
@@ -762,7 +761,7 @@ flower = inject(FlowerService, {skipSelf: true});
次に、 `` の `ModuleInjector` に戻り、 `` と `` が同じ `ModuleInjector` を共有しているため、赤いハイビスカス 🌺 値が見つかります。
UIには次のように表示されます。
-```shell
+```text {hideCopy}
Emoji from FlowerService: 🌺
```
@@ -847,7 +846,7 @@ Emoji from FlowerService: 🌺
### `host` と `viewProviders` {#host-and-viewproviders}
`AnimalService`のインジェクションに`host`だけを使用する場合、インジェクターは``の`<#VIEW>`自体で`AnimalService`を見つけるため、結果は犬🐶になります。
-`ChildComponent`は`viewProviders`を設定し、犬の絵文字が`AnimalService`の値として提供されます。
+`Child`は`viewProviders`を設定し、犬の絵文字が`AnimalService`の値として提供されます。
`inject()`では`host`も使用できます:
```typescript
@@ -858,7 +857,7 @@ Emoji from FlowerService: 🌺
{ provide: AnimalService, useValue: { emoji: '🐶' } },
]
})
-export class ChildComponent {
+export class Child {
animal = inject(AnimalService, { host: true })
}
```
@@ -884,19 +883,19 @@ export class ChildComponent {
```typescript
@Component({
selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: [ './app.component.css' ],
+ templateUrl: './app.html',
+ styleUrls: [ './app.css' ],
viewProviders: [
{ provide: AnimalService, useValue: { emoji: '🦔' } },
],
})
```
-次に、`child.component.ts` の `AnimalService` 注入の `inject()` に `host` とともに `skipSelf` を追加します。
+次に、`child.ts` の `AnimalService` 注入の `inject()` に `host` とともに `skipSelf` を追加します。
`animal` プロパティの初期化における `host` と `skipSelf` は次のとおりです。
```typescript
-export class ChildComponent {
+export class Child {
animal = inject(AnimalService, {host: true, skipSelf: true});
}
```
@@ -908,7 +907,7 @@ export class ChildComponent {
`providers` 配列にある `FlowerService` に `host` と `skipSelf` を適用した場合、結果は `null` でした。これは、`skipSelf` が `` インジェクターで検索を開始しますが、`host` は `<#VIEW>` で検索を停止するためです。そこには `FlowerService` がありません。
論理ツリーでは、 `FlowerService` は `` で可視であり、 `<#VIEW>` では可視ではないことがわかります。
-ただし、 `AppComponent` の `viewProviders` 配列で提供されている `AnimalService` は可視です。
+ただし、 `App` の `viewProviders` 配列で提供されている `AnimalService` は可視です。
論理ツリーの表現は、これが理由を示しています。
@@ -940,34 +939,34 @@ export class ChildComponent {
### シナリオ:サービスの分離 {#scenario-service-isolation}
アーキテクチャ上の理由から、サービスへのアクセスを属するアプリケーションドメインに制限する必要がある場合があります。
-たとえば、悪役のリストを表示する `VillainsListComponent` を構築するとします。
+たとえば、悪役のリストを表示する `VillainsList` を構築するとします。
この悪役は、 `VillainsService` から取得されます。
`VillainsService` をルートの `AppModule` で提供すると、 `VillainsService` がアプリケーションのすべての場所で可視になります。
後で `VillainsService` を変更した場合、誤ってこのサービスに依存し始めた他のコンポーネントで何かが壊れる可能性があります。
-代わりに、次のように `VillainsListComponent` の `providers` メタデータで `VillainsService` を提供する必要があります。
+代わりに、次のように `VillainsList` の `providers` メタデータで `VillainsService` を提供する必要があります。
```typescript
@Component({
selector: 'app-villains-list',
- templateUrl: './villains-list.component.html',
+ templateUrl: './villains-list.html',
providers: [VillainsService],
})
-export class VillainsListComponent {}
+export class VillainsList {}
```
-`VillainsService` を `VillainsListComponent` メタデータで提供し、他の場所では提供しないと、サービスは `VillainsListComponent` とそのサブコンポーネントツリーのみに使用可能になります。
+`VillainsService` を `VillainsList` メタデータで提供し、他の場所では提供しないと、サービスは `VillainsList` とそのサブコンポーネントツリーのみに使用可能になります。
-`VillainService` は、 `VillainsListComponent` に対してシングルトンです。なぜなら、それが宣言されている場所だからです。
-`VillainsListComponent` が破棄されない限り `VillainService` のインスタンスは同じです。ただし `VillainsListComponent` のインスタンスが複数ある場合、 `VillainsListComponent` の各インスタンスには、独自の `VillainService` インスタンスが1つずつあります。
+`VillainsService` は、 `VillainsList` に対してシングルトンです。なぜなら、それが宣言されている場所だからです。
+`VillainsList` が破棄されない限り `VillainsService` のインスタンスは同じです。ただし `VillainsList` のインスタンスが複数ある場合、 `VillainsList` の各インスタンスには、独自の `VillainsService` インスタンスが1つずつあります。
### シナリオ:複数の編集セッション {#scenario-multiple-edit-sessions}
多くのアプリケーションでは、ユーザーは同時に複数のオープンタスクで作業できます。
たとえば、税務申告の作成アプリケーションでは、作成者は複数の税務申告で作業し、1日を通してそれらを切り替えることができます。
-そのシナリオを示すために、スーパーヒーローのリストを表示する `HeroListComponent` を考えてみてください。
+そのシナリオを示すために、スーパーヒーローのリストを表示する `HeroList` を考えてみてください。
ヒーローの税務申告を開くために、作成者はヒーローの名前をクリックすると、その申告を編集するためのコンポーネントが開きます。
選択したヒーローの税務申告は、それぞれ独自のコンポーネントで開き、複数の申告を同時に開くことができます。
@@ -978,7 +977,7 @@ export class VillainsListComponent {}
- 別のコンポーネントの申告に影響を与えずに税務申告を変更できます
- 税務申告の変更を保存するか、キャンセルする機能があります
-`HeroTaxReturnComponent` に、変更を管理および復元するためのロジックがあるとします。
+`HeroTaxReturn` に、変更を管理および復元するためのロジックがあるとします。
これは、ヒーローの税務申告にとっては簡単なタスクです。
現実世界では、豊富な税務申告データモデルでは、変更管理が複雑になります。
この例のように、この管理をヘルパーサービスに委任できます。
@@ -1018,7 +1017,7 @@ export class HeroTaxReturnService {
}
```
-以下は、 `HeroTaxReturnService` を使用する `HeroTaxReturnComponent` です。
+以下は、 `HeroTaxReturnService` を使用する `HeroTaxReturn` です。
```typescript
import {Component, input, output} from '@angular/core';
@@ -1027,11 +1026,11 @@ 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'],
+ templateUrl: './hero-tax-return.html',
+ styleUrls: ['./hero-tax-return.css'],
providers: [HeroTaxReturnService],
})
-export class HeroTaxReturnComponent {
+export class HeroTaxReturn {
message = '';
close = output();
@@ -1079,13 +1078,13 @@ _編集対象の税務申告_ は、 `input` プロパティを介して到着
これは、サービスがアプリケーション全体のシングルトンである場合に機能しません。
すべてのコンポーネントは同じサービスインスタンスを共有し、各コンポーネントは別のヒーローに属する税務申告を上書きします。
-これを防ぐために、コンポーネントレベルのインジェクター `HeroTaxReturnComponent` を構成して、コンポーネントメタデータの `providers` プロパティを使用してサービスを提供します。
+これを防ぐために、コンポーネントレベルのインジェクター `HeroTaxReturn` を構成して、コンポーネントメタデータの `providers` プロパティを使用してサービスを提供します。
```typescript
providers: [HeroTaxReturnService];
```
-`HeroTaxReturnComponent` には、 `HeroTaxReturnService` の独自の提供者がいます。
+`HeroTaxReturn` には、 `HeroTaxReturnService` の独自の提供者がいます。
覚えておいてください。すべてのコンポーネントの _インスタンス_ には、独自のインジェクターがあります。
コンポーネントレベルでサービスを提供すると、コンポーネントの _すべての_ インスタンスは、サービスのプライベートインスタンスを1つずつ取得することが保証されます。これにより、税務申告が上書きされないようにします。
@@ -1170,5 +1169,5 @@ 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 a4f13143db..588c36762f 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
@@ -22,11 +22,10 @@ To prevent the retention of unused components, your library should use the light
To better explain the condition under which token retention occurs, consider a library that provides a library-card component.
This component contains a body and can contain an optional header:
-```angular-html
-
-;
-…;
-;
+```html
+
+ …
+
```
In a likely implementation, the `` component uses `contentChild` or `contentChildren` to get `` and ``, as in the following:
@@ -91,7 +90,7 @@ Although tokens used only as type specifiers are removed when converted to JavaS
When using `inject(CustomOther)`, `CustomOther` is passed as a value argument.
The token is now in a value position, which causes the tree-shaker to keep the reference.
-HELPFUL: Libraries should use [tree-shakable providers](guide/di/dependency-injection#providing-dependency) for all services, providing dependencies at the root level rather than in components or modules.
+HELPFUL: Libraries should use [tree-shakable providers](guide/di/defining-dependency-providers) for all services, providing dependencies at the root level rather than in components or modules.
## Using lightweight injection tokens
@@ -144,7 +143,7 @@ This lets the parent communicate with the child, if it is present, in a type-saf
For example, the `LibCard` now queries `LibHeaderToken` rather than `LibHeader`.
The following example shows how the pattern lets `LibCard` communicate with the `LibHeader` without actually referring to `LibHeader`:
-```ts {highlight: [[2],[9],[11],[19]]}
+```ts {highlight: [[2],[7],[11],[19]]}
abstract class LibHeaderToken {
abstract doSomething(): void;
}
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 71ca7f2795..d00a32ea40 100644
--- a/adev-ja/src/content/guide/di/lightweight-injection-tokens.md
+++ b/adev-ja/src/content/guide/di/lightweight-injection-tokens.md
@@ -22,11 +22,10 @@ Angularがインジェクショントークンを格納する方法により、
トークン保持が発生する状況をより明確に説明するために、ライブラリカードコンポーネントを提供するライブラリを検討してください。
このコンポーネントには本体が含まれており、オプションでヘッダーを含めることができます。
-```angular-html
-
-;
-…;
-;
+```html
+
+ …
+
```
一般的な実装では、 `` コンポーネントは、次の例のように `contentChild` または `contentChildren` を使用して `` と `` を取得します。
@@ -91,7 +90,7 @@ class MyComponent {
これらは実質的に `constructor(@Optional() other: OtherComponent)` を `constructor(@Optional() @Inject(OtherComponent) other)` に変更されます。
トークンはこれで値位置にあるため、ツリーシェーカーは参照を保持します。
-HELPFUL: ライブラリは、[ツリーシェイク可能なプロバイダー](guide/di/dependency-injection#providing-dependency) をすべてのサービスに使用し、コンポーネントやモジュールではなく、ルートレベルで依存関係を提供する必要があります。
+HELPFUL: ライブラリは、[ツリーシェイク可能なプロバイダー](guide/di/defining-dependency-providers) をすべてのサービスに使用し、コンポーネントやモジュールではなく、ルートレベルで依存関係を提供する必要があります。
## 軽量インジェクショントークンの使用
@@ -144,7 +143,7 @@ class LibCardComponent {
たとえば、 `LibCardComponent` はこれで `LibHeaderComponent` ではなく `LibHeaderToken` をクエリします。
次の例は、パターンにより `LibCardComponent` が `LibHeaderComponent` を実際に参照せずに `LibHeaderComponent` と通信する方法を示しています。
-```ts {highlight: [[2],[9],[11],[19]]}
+```ts {highlight: [[2],[7],[11],[19]]}
abstract class LibHeaderToken {
abstract doSomething(): void;
}
diff --git a/adev-ja/src/content/guide/di/overview.en.md b/adev-ja/src/content/guide/di/overview.en.md
index cb0829d211..879dd8e8a0 100644
--- a/adev-ja/src/content/guide/di/overview.en.md
+++ b/adev-ja/src/content/guide/di/overview.en.md
@@ -69,17 +69,15 @@ 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';
+import {Component, inject} from '@angular/core';
+import {Router} from '@angular/router';
+import {AnalyticsLogger} from './analytics-logger';
@Component({
selector: 'app-navbar',
- template: `
- Detail Page
- `,
+ template: `Detail Page`,
})
-export class NavbarComponent {
+export class Navbar {
private router = inject(Router);
private analytics = inject(AnalyticsLogger);
@@ -96,7 +94,9 @@ export class NavbarComponent {
You can inject dependencies during construction of a component, directive, or service. The call to [`inject`](/api/core/inject) can appear in either the `constructor` or in a field initializer. Here are some common examples:
```ts
-@Component({...})
+@Component({
+ /*...*/
+})
export class MyComponent {
// ✅ In class field initializer
private service = inject(MyService);
diff --git a/adev-ja/src/content/guide/di/overview.md b/adev-ja/src/content/guide/di/overview.md
index e2964a7e44..4503768c05 100644
--- a/adev-ja/src/content/guide/di/overview.md
+++ b/adev-ja/src/content/guide/di/overview.md
@@ -69,17 +69,15 @@ Angularの `inject()` 関数を使用して依存関係を注入できます。
次は、`AnalyticsLogger` とAngularの `Router` サービスを注入して、イベントを追跡しながらユーザーが別のページに移動できるようにするナビゲーションバーの例です。
```angular-ts
-import { Component, inject } from '@angular/core';
-import { Router } from '@angular/router';
-import { AnalyticsLogger } from './analytics-logger';
+import {Component, inject} from '@angular/core';
+import {Router} from '@angular/router';
+import {AnalyticsLogger} from './analytics-logger';
@Component({
selector: 'app-navbar',
- template: `
- Detail Page
- `,
+ template: `Detail Page`,
})
-export class NavbarComponent {
+export class Navbar {
private router = inject(Router);
private analytics = inject(AnalyticsLogger);
@@ -96,7 +94,9 @@ export class NavbarComponent {
コンポーネント、ディレクティブ、またはサービスの構築中に依存関係を注入できます。[`inject`](/api/core/inject) の呼び出しは、`constructor` またはフィールドイニシャライザーのいずれかに配置できます。一般的な例をいくつか示します。
```ts
-@Component({...})
+@Component({
+ /*...*/
+})
export class MyComponent {
// ✅ クラスフィールドイニシャライザー内
private service = inject(MyService);
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 e072054840..f5af756de7 100644
--- a/adev-ja/src/content/guide/directives/attribute-directives.en.md
+++ b/adev-ja/src/content/guide/directives/attribute-directives.en.md
@@ -121,7 +121,7 @@ This section guides you through configuring your application so the developer ca
3. 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 the value is a static string, not a dynamic expression.
diff --git a/adev-ja/src/content/guide/directives/attribute-directives.md b/adev-ja/src/content/guide/directives/attribute-directives.md
index f4ec819d25..dc35f294b1 100644
--- a/adev-ja/src/content/guide/directives/attribute-directives.md
+++ b/adev-ja/src/content/guide/directives/attribute-directives.md
@@ -122,7 +122,7 @@ HELPFUL: ハンドラーは、ホストDOM要素`el`に色を設定するヘル
3. `AppComponent.color`にバインドし、デフォルトカラーとして「violet」を使用するには、次のHTMLを追加します。
- この場合、`defaultColor`バインディングは、静的であるため、角括弧`[]`を使用しません。
+ この場合、`defaultColor`バインディングは、動的な式ではなく静的な文字列であるため、角括弧`[]`を使用しません。
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 4dce2bfe6f..f6bda5e079 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
@@ -60,8 +60,7 @@ By explicitly specifying the inputs and outputs, consumers of the component with
bind them in a template:
```angular-html
-
-
+
```
Furthermore, you can alias inputs and outputs from `hostDirective` to customize the API of your
@@ -83,8 +82,7 @@ export class AdminMenu {}
```
```angular-html
-
-
+
```
## Adding directives to another directive
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 faf9391d6b..4010477391 100644
--- a/adev-ja/src/content/guide/directives/directive-composition-api.md
+++ b/adev-ja/src/content/guide/directives/directive-composition-api.md
@@ -60,8 +60,7 @@ export class AdminMenu {}
テンプレートでそれらにバインドできます。
```angular-html
-
-
+
```
さらに、`hostDirective` から入力と出力をエイリアスして、
@@ -83,8 +82,7 @@ export class AdminMenu {}
```
```angular-html
-
-
+
```
## 別のディレクティブにディレクティブを追加する
diff --git a/adev-ja/src/content/guide/directives/overview.en.md b/adev-ja/src/content/guide/directives/overview.en.md
index ed218a3f1c..287f986e28 100644
--- a/adev-ja/src/content/guide/directives/overview.en.md
+++ b/adev-ja/src/content/guide/directives/overview.en.md
@@ -32,7 +32,7 @@ HELPFUL: Built-in directives use only public APIs. They do not have special acce
Add or remove multiple CSS classes simultaneously with `ngClass`.
-HELPFUL: To add or remove a _single_ class, use [class binding](guide/templates/class-binding) rather than `NgClass`.
+HELPFUL: To add or remove a _single_ class, use [class binding](/guide/templates/binding#css-class-and-style-property-bindings) rather than `NgClass`.
### Import `NgClass` in the component
diff --git a/adev-ja/src/content/guide/directives/overview.md b/adev-ja/src/content/guide/directives/overview.md
index 1b23d2ac91..0058c3ed1e 100644
--- a/adev-ja/src/content/guide/directives/overview.md
+++ b/adev-ja/src/content/guide/directives/overview.md
@@ -32,7 +32,7 @@ HELPFUL: 組み込みディレクティブは、公開APIのみを使用しま
`ngClass` を使用して、複数のCSSクラスを同時に追加または削除します。
-HELPFUL: _単一の_ クラスを追加または削除するには、`NgClass` ではなく [クラスバインディング](guide/templates/class-binding) を使用します。
+HELPFUL: _単一の_ クラスを追加または削除するには、`NgClass` ではなく [クラスバインディング](/guide/templates/binding#css-class-and-style-property-bindings) を使用します。
### コンポーネントに `NgClass` をインポートする
diff --git a/adev-ja/src/content/guide/directives/structural-directives.en.md b/adev-ja/src/content/guide/directives/structural-directives.en.md
index 0e696ce225..8751f2b8a0 100644
--- a/adev-ja/src/content/guide/directives/structural-directives.en.md
+++ b/adev-ja/src/content/guide/directives/structural-directives.en.md
@@ -31,7 +31,7 @@ Structural directives can be applied directly on an element by prefixing the dir
You can use this with `SelectDirective` as follows:
```angular-html
-
The data is: {{data}}
+
The data is: {{ data }}
```
This example shows the flexibility of structural directive shorthand syntax, which is sometimes called _microsyntax_.
@@ -40,11 +40,11 @@ When used in this way, only the structural directive and its bindings are applie
```angular-html
-
```
@@ -167,7 +167,7 @@ Angularは、構造ディレクティブの省略記法を次の通常のバイ
| `*ngComponentOutlet="componentClass; inputs: myInputs";` | `` |
| `*myDir="exp as value"` | `` |
-## カスタムディレクティブのテンプレートタイプチェックを改善する
+## カスタムディレクティブのテンプレートタイプチェックを改善する {#improving-template-type-checking-for-custom-directives}
カスタムディレクティブのテンプレートタイプチェックを改善するには、ディレクティブ定義にテンプレートガードを追加します。
これらのガードは、Angularテンプレートタイプチェッカーがコンパイル時にテンプレート内の間違いを見つけるのに役立ち、ランタイムエラーを回避できます。
diff --git a/adev-ja/src/content/guide/drag-drop.md b/adev-ja/src/content/guide/drag-drop.md
index c33451438e..2e2aebbe35 100644
--- a/adev-ja/src/content/guide/drag-drop.md
+++ b/adev-ja/src/content/guide/drag-drop.md
@@ -34,8 +34,8 @@ import {Component} from '@angular/core';
import {CdkDrag} from '@angular/cdk/drag-drop';
@Component({
- selector: 'my-custom-component',
- templateUrl: 'my-custom-component.html',
+ selector: 'drag-drop-example',
+ templateUrl: 'drag-drop-example.html',
imports: [CdkDrag],
})
export class DragDropExample {}
@@ -45,10 +45,10 @@ export class DragDropExample {}
You can make any element draggable by adding the `cdkDrag` directive. By default, all draggable elements support free dragging.
-
-
-
-
+
+
+
+
## Create a list of reorderable draggable elements
@@ -57,10 +57,10 @@ Add the `cdkDropList` directive to a parent element to group draggable elements
The drag and drop directives don't update your data model. To update the data model, listen to the `cdkDropListDropped` event (once the user finishes dragging) and update the data model manually.
-
-
-
-
+
+
+
+
You can use the `CDK_DROP_LIST` injection token that can be used to reference instances of `cdkDropList`. For more information see the [dependency injection guide](/guide/di) and the [drop list injection token API](api/cdk/drag-drop/CDK_DROP_LIST).
@@ -84,27 +84,27 @@ The `cdkDropListConnectedTo` directive works both with a direct reference to ano
```
-
-
-
-
+
+
+
+
Use the `cdkDropListGroup` directive if you have an unknown number of connected drop lists to set up the connection automatically. Any new `cdkDropList` that is added under a group automatically connects to all other lists.
-```html
+```angular-html
@for (list of lists; track list) {
-
+
}
```
-
-
-
-
+
+
+
+
You can use the `CDK_DROP_LIST_GROUP` injection token that can be used to reference instances of `cdkDropListGroup`. For more information see the [dependency injection guide](/guide/di) and the [drop list group injection token API](api/cdk/drag-drop/CDK_DROP_LIST_GROUP).
@@ -113,23 +113,23 @@ You can use the `CDK_DROP_LIST_GROUP` injection token that can be used to refere
By default, a user can move `cdkDrag` elements from one container into another connected container. For more fine-grained control over which elements can be dropped into a container, use `cdkDropListEnterPredicate`. Angular calls the predicate whenever a draggable element enters a new container. Depending on whether the predicate returns true or false, the item may or may not be allowed into the new container.
-
-
-
-
+
+
+
+
## Attach data
You can associate some arbitrary data with both `cdkDrag` and `cdkDropList` by setting `cdkDragData` or `cdkDropListData`, respectively. You can bind to the events fired from both directives that will include this data, allowing you to easily identify the origin of the drag or drop interaction.
-```html
+```angular-html
@for (list of lists; track list) {
-
- @for (item of list; track item) {
-
- }
-
+
+ @for (item of list; track item) {
+
+ }
+
}
```
@@ -139,10 +139,10 @@ You can associate some arbitrary data with both `cdkDrag` and `cdkDropList` by s
By default, the user can drag the entire `cdkDrag` element to move it around. To restrict the user to only be able to do so using a handle element, add the `cdkDragHandle` directive to an element inside of `cdkDrag`. You can have as many `cdkDragHandle` elements as you want.
-
-
-
-
+
+
+
+
You can use the `CDK_DRAG_HANDLE` injection token that can be used to reference instances of `cdkDragHandle`. For more information see the [dependency injection guide](/guide/di) and the [drag handle injection token API](api/cdk/drag-drop/CDK_DRAG_HANDLE).
@@ -155,10 +155,10 @@ To customize the preview, provide a custom template via `*cdkDragPreview`. The c
The cloned element removes its id attribute in order to avoid having multiple elements with the same id on the page. This will cause any CSS that targets that id not to be applied.
-
-
-
-
+
+
+
+
You can use the `CDK_DRAG_PREVIEW` injection token that can be used to reference instances of `cdkDragPreview`. For more information see the [dependency injection guide](/guide/di) and the [drag preview injection token API](api/cdk/drag-drop/CDK_DRAG_PREVIEW).
@@ -181,10 +181,10 @@ Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update `p
While a `cdkDrag` element is being dragged, the directive creates a placeholder element that shows where the element will be placed when dropped. By default, the placeholder is a clone of the element that is being dragged. You can replace the placeholder with a custom one using the `*cdkDragPlaceholder` directive:
-
-
-
-
+
+
+
+
You can use the `CDK_DRAG_PLACEHOLDER` injection token that can be used to reference instances of `cdkDragPlaceholder`. For more information see the [dependency injection guide](/guide/di) and the [drag placeholder injection token API](api/cdk/drag-drop/CDK_DRAG_PLACEHOLDER).
@@ -195,10 +195,10 @@ Set the `cdkDragRootElement` attribute if there's an element that you want to ma
The attribute accepts a selector and looks up the DOM until it finds an element that matches the selector. If an element is found, it becomes draggable. This is useful for cases such as making a dialog draggable.
-
-
-
-
+
+
+
+
Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update `rootElementSelector` within the config. For more information see the [dependency injection guide](/guide/di), [drag config injection token API](api/cdk/drag-drop/CDK_DRAG_CONFIG), and the [drag drop config API](api/cdk/drag-drop/DragDropConfig).
@@ -207,20 +207,20 @@ Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update `r
By default, `cdkDrag` elements not in a `cdkDropList` move from their normal DOM position only when a user manually moves the element. Use the `cdkDragFreeDragPosition` input to explicitly set the element’s position. A common use case for this is restoring a draggable element's position after a user has navigated away and then returned.
-
-
-
-
+
+
+
+
### Restrict movement within an element
To stop the user from being able to drag a `cdkDrag` element outside of another element, pass a CSS selector to the `cdkDragBoundary` attribute. This attribute accepts a selector and looks up the DOM until it finds an element that matches it. If a match is found, the element becomes the boundary that the draggable element can't be dragged outside of `cdkDragBoundary` can also be used when `cdkDrag` is placed inside a `cdkDropList`.
-
-
-
-
+
+
+
+
Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update boundaryElement within the config. For more information see the [dependency injection guide](/guide/di), [drag config injection token API](api/cdk/drag-drop/CDK_DRAG_CONFIG), and the [drag drop config API](api/cdk/drag-drop/DragDropConfig).
@@ -229,10 +229,10 @@ Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update bo
By default, `cdkDrag` allows free movement in all directions. To restrict dragging to a specific axis, set `cdkDragLockAxis` to either "x" or "y"on `cdkDrag`. To restrict dragging for multiple draggable elements within `cdkDropList`, set `cdkDropListLockAxis` on `cdkDropList` instead.
-
-
-
-
+
+
+
+
Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update `lockAxis` within the config. For more information see the [dependency injection guide](/guide/di), [drag config injection token API](api/cdk/drag-drop/CDK_DRAG_CONFIG), and the [drag drop config API](api/cdk/drag-drop/DragDropConfig).
@@ -243,10 +243,10 @@ By default when the user puts their pointer down on a `cdkDrag`, the dragging se
You can delay the dragging sequence using the `cdkDragStartDelay` input. The input waits for the user to hold down their pointer for the specified number of milliseconds before dragging the element.
-
-
-
-
+
+
+
+
Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update dragStartDelay within the config. For more information see the [dependency injection guide](/guide/di), [drag config injection token API](api/cdk/drag-drop/CDK_DRAG_CONFIG), and the [drag drop config API](api/cdk/drag-drop/DragDropConfig).
@@ -255,10 +255,10 @@ Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update dr
If you want to disable dragging for a particular drag item, set the `cdkDragDisabled` input on a `cdkDrag` item to true or false. You can disable an entire list using the `cdkDropListDisabled` input on a `cdkDropList`. It is also possible to disable a specific handle via `cdkDragHandleDisabled` on `cdkDragHandle`.
-
-
-
-
+
+
+
+
Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update `draggingDisabled` within the config. For more information see the [dependency injection guide](/guide/di), [drag config injection token API](api/cdk/drag-drop/CDK_DRAG_CONFIG), and the [drag drop config API](api/cdk/drag-drop/DragDropConfig).
@@ -269,10 +269,10 @@ Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update `d
By default, the `cdkDropList` directive assumes lists are vertical. This can be changed by setting the `cdkDropListOrientation` property to horizontal.
-
-
-
-
+
+
+
+
Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update `listOrientation` within the config. For more information see the [dependency injection guide](/guide/di), [drag config injection token API](api/cdk/drag-drop/CDK_DRAG_CONFIG), and the [drag drop config API](api/cdk/drag-drop/DragDropConfig).
@@ -283,30 +283,30 @@ By default, the `cdkDropList` sorts the draggable elements by moving them around
If you have a sortable list that needs to wrap onto new lines, you can set `cdkDropListOrientation` attribute to `mixed`. This causes the list to use a different strategy of sorting the elements which involves moving them in the DOM. However the list can no longer animate the sorting action .
-
-
-
-
+
+
+
+
### Selective sorting
By default, `cdkDrag` elements are sorted into any position inside of a `cdkDropList`. To change this behavior, set the `cdkDropListSortPredicate` attribute which takes in a function. The predicate function is called whenever a draggable element is about to be moved into a new index within the drop list. If the predicate returns true, the item will be moved into the new index, otherwise it will keep its current position.
-
-
-
-
+
+
+
+
### Disable sorting
There are cases where draggable elements can be dragged out of one `cdkDropList` into another, however the user shouldn't be able to sort them within the source list. For these cases, add the `cdkDropListSortingDisabled` attribute to prevent the draggable elements in a `cdkDropList` from sorting. This preserves the dragged element's initial position in the source list if it does not get dragged to a new valid position.
-
-
-
-
+
+
+
+
Alternatively, you can modify the `CDK_DRAG_CONFIG` injection token to update sortingDisabled within the config. For more information see the [dependency injection guide](/guide/di), [drag config injection token API](api/cdk/drag-drop/CDK_DRAG_CONFIG), and the [drag drop config API](api/cdk/drag-drop/DragDropConfig).
@@ -319,10 +319,10 @@ To enable copying, you can set the `cdkDropListHasAnchor` input. This tells the
Combining `cdkDropListHasAnchor` with `cdkDropListSortingDisabled` makes it possible to construct a list from which a user can copy items without being able to reorder the source list (e.g. a product list and a shopping cart).
-
-
-
-
+
+
+
+
## Customize animations
diff --git a/adev-ja/src/content/guide/elements.en.md b/adev-ja/src/content/guide/elements.en.md
index 90bb9d2e34..44daf9eec7 100644
--- a/adev-ja/src/content/guide/elements.en.md
+++ b/adev-ja/src/content/guide/elements.en.md
@@ -63,7 +63,7 @@ One regular Angular component and a second one using the custom element.
### Mapping
A custom element _hosts_ an Angular component, providing a bridge between the data and logic defined in the component and standard DOM APIs.
-Component properties and logic maps directly into HTML attributes and the browser's event system.
+Component properties and logic map directly into HTML attributes and the browser's event system.
- The creation API parses the component looking for input properties, and defines corresponding attributes for the custom element.
It transforms the property names to make them compatible with custom elements, which do not recognize case distinctions.
@@ -71,10 +71,10 @@ Component properties and logic maps directly into HTML attributes and the browse
For example, for a component with `inputProp = input({alias: 'myInputProp'})`, the corresponding custom element defines an attribute `my-input-prop`.
- Component outputs are dispatched as HTML [Custom Events](https://developer.mozilla.org/docs/Web/API/CustomEvent), with the name of the custom event matching the output name.
- For example, for a component `with valueChanged = output()`, the corresponding custom element dispatches events with the name "valueChanged", and the emitted data is stored on the event's `detail` property.
+ For example, for a component with `valueChanged = output()`, the corresponding custom element dispatches events with the name "valueChanged", and the emitted data is stored on the event's `detail` property.
If you provide an alias, that value is used; for example, `clicks = output({alias: 'myClick'});` results in dispatch events with the name "myClick".
-For more information, see Web Component documentation for [Creating custom events](https://developer.mozilla.org/docs/Web/Guide/Events/Creating_and_triggering_events#Creating_custom_events).
+For more information, see Web Component documentation for [Creating custom events](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Events#creating_custom_events).
## Example: A Popup Service
@@ -85,20 +85,20 @@ Using an Angular custom element makes the process simpler and more transparent,
The following Popup Service example application defines a component that you can either load dynamically or convert to a custom element.
-| Files | Details |
-| :------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `popup.component.ts` | Defines a simple pop-up element that displays an input message, with some animation and styling. |
-| `popup.service.ts` | Creates an injectable service that provides two different ways to invoke the `PopupComponent`; as a dynamic component, or as a custom element. Notice how much more setup is required for the dynamic-loading method. |
-| `app.component.ts` | Defines the application's root component, which uses the `PopupService` to add the pop-up to the DOM at run time. When the application runs, the root component's constructor converts `PopupComponent` to a custom element. |
+| Files | Details |
+| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `popup.ts` | Defines a simple pop-up element that displays an input message, with some animation and styling. |
+| `popup.service.ts` | Creates an injectable service that provides two different ways to invoke the `Popup`; as a dynamic component, or as a custom element. Notice how much more setup is required for the dynamic-loading method. |
+| `app.ts` | Defines the application's root component, which uses the `PopupService` to add the pop-up to the DOM at run time. When the application runs, the root component's constructor converts `Popup` to a custom element. |
For comparison, the demo shows both methods.
One button adds the popup using the dynamic-loading method, and the other uses the custom element.
The result is the same, but the preparation is different.
-
+
-
+
## Typings for custom elements
@@ -119,7 +119,7 @@ Assume you create a `my-dialog` custom element based on the following component:
```ts
@Component(/* ... */)
class MyDialog {
- content = input(string);
+ content = input('');
}
```
@@ -164,5 +164,5 @@ document.querySelector('my-other-element'); //--> NgElement & WithProperties<{fo
Care should be taken when destroying and then re-attaching custom elements created with `@angular/elements` due to issues with the [disconnect()](https://github.com/angular/angular/issues/38778) callback. Cases where you may run into this issue are:
-- Rendering a component in an `ng-if` or `ng-repeat` in `AngularJs`
+- Rendering a component in an `ng-if` or `ng-repeat` in `AngularJS`
- Manually detaching and re-attaching an element to the DOM
diff --git a/adev-ja/src/content/guide/elements.md b/adev-ja/src/content/guide/elements.md
index e09c66fbe4..6664502991 100644
--- a/adev-ja/src/content/guide/elements.md
+++ b/adev-ja/src/content/guide/elements.md
@@ -63,7 +63,7 @@ IMPORTANT: コンポーネントのセレクターをカスタム要素のタグ
### マッピング {#mapping}
カスタム要素はAngularコンポーネントを_ホスト_し、コンポーネントで定義されたデータとロジック、および標準のDOM API間のブリッジを提供します。
-コンポーネントのプロパティとロジックは、HTML属性とブラウザのイベントシステムに直接マッピングされます。
+コンポーネントのプロパティとロジックは、HTML属性とブラウザのイベントシステムに直接マップされます。
- 作成APIは、入力プロパティを探してコンポーネントを解析し、カスタム要素に対応する属性を定義します。
プロパティ名をカスタム要素と互換性があるように変換します。カスタム要素は大文字と小文字の区別を認識しません。
@@ -72,9 +72,9 @@ IMPORTANT: コンポーネントのセレクターをカスタム要素のタグ
- コンポーネントの出力はHTMLの[カスタムイベント](https://developer.mozilla.org/docs/Web/API/CustomEvent)としてディスパッチされ、カスタムイベントの名前は出力名と一致します。
例えば、`valueChanged = output()`を持つコンポーネントの場合、対応するカスタム要素は"valueChanged"という名前のイベントをディスパッチし、出力されたデータはイベントの`detail`プロパティに格納されます。
- エイリアスを提供した場合、その値が使用されます。`clicks = output({alias: 'myClick'});`は"myClick"という名前のディスパッチイベントを生成します。
+ エイリアスを提供した場合、その値が使用されます。たとえば、`clicks = output({alias: 'myClick'});`は"myClick"という名前のディスパッチイベントを生成します。
-詳細については、Webコンポーネントのドキュメントの[カスタムイベントの作成](https://developer.mozilla.org/docs/Web/Guide/Events/Creating_and_triggering_events#Creating_custom_events)を参照してください。
+詳細については、Webコンポーネントのドキュメントの[カスタムイベントの作成](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Events#creating_custom_events)を参照してください。
## 例: Popupサービス {#example-a-popup-service}
@@ -85,20 +85,20 @@ Angularカスタム要素を使用すると、必要なインフラストラク
以下のPopupサービス例のアプリケーションは、動的にロードするかカスタム要素に変換できるコンポーネントを定義しています。
-| ファイル | 詳細 |
-| :-------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `popup.component.ts` | 入力メッセージを表示するシンプルなポップアップ要素を、アニメーションとスタイル付きで定義します。 |
-| `popup.service.ts` | `PopupComponent`を呼び出す2つの異なる方法を提供する注入可能サービスを作成します。動的コンポーネントとして、またはカスタム要素として。動的読み込み方式には、より多くのセットアップが必要であることに注目してください。 |
-| `app.component.ts` | `PopupService`を使用して実行時にDOMにポップアップを追加する、アプリケーションのルートコンポーネントを定義します。アプリケーションの実行時、ルートコンポーネントのコンストラクターは`PopupComponent`をカスタム要素に変換します。 |
+| ファイル | 詳細 |
+| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `popup.ts` | 入力メッセージを表示するシンプルなポップアップ要素を、アニメーションとスタイル付きで定義します。 |
+| `popup.service.ts` | `Popup`を呼び出す2つの異なる方法を提供する注入可能サービスを作成します。動的コンポーネントとして、またはカスタム要素として。動的読み込み方式には、より多くのセットアップが必要であることに注目してください。 |
+| `app.ts` | `PopupService`を使用して実行時にDOMにポップアップを追加する、アプリケーションのルートコンポーネントを定義します。アプリケーションの実行時、ルートコンポーネントのコンストラクターは`Popup`をカスタム要素に変換します。 |
比較のため、デモでは両方の方法を示しています。
一方のボタンは動的読み込み方式を使用してポップアップを追加し、もう一方はカスタム要素を使用します。
結果は同じですが、準備が異なります。
-
+
-
+
## カスタム要素の型定義 {#typings-for-custom-elements}
@@ -119,7 +119,7 @@ Angularで作成されたカスタム要素は`NgElement`(これはさらに`H
```ts
@Component(/* ... */)
class MyDialog {
- content = input(string);
+ content = input('');
}
```
diff --git a/adev-ja/src/content/guide/forms/form-validation.en.md b/adev-ja/src/content/guide/forms/form-validation.en.md
index ca5aad51da..07d9d9d675 100644
--- a/adev-ja/src/content/guide/forms/form-validation.en.md
+++ b/adev-ja/src/content/guide/forms/form-validation.en.md
@@ -250,9 +250,9 @@ A common UI pattern is to show a spinner while the async validation is being per
The following example shows how to achieve this in a template-driven form.
```angular-html
-
+
-@if(model.pending) {
+@if (model.pending) {
}
```
@@ -278,7 +278,7 @@ interface ActorsService {
In a real world application, the `ActorsService` would be responsible for making an HTTP request to the actor database to check if the role is available.
From the validator's point of view, the actual implementation of the service is not important, so the example can just code against the `ActorsService` interface.
-As the validation begins, the `UnambiguousRoleValidator` delegates to the `ActorsService` `isRoleTaken()` method with the current control value.
+As the validation begins, the `UniqueRoleValidator` delegates to the `ActorsService` `isRoleTaken()` method with the current control value.
At this point the control is marked as `pending` and remains in this state until the observable chain returned from the `validate()` method completes.
The `isRoleTaken()` method dispatches an HTTP request that checks if the role is available, and returns `Observable` as the result.
@@ -300,7 +300,7 @@ To use an async validator in reactive forms, begin by injecting the validator in
Then, pass the validator function directly to the `FormControl` to apply it.
-In the following example, the `validate` function of `UnambiguousRoleValidator` is applied to `roleControl` by passing it to the control's `asyncValidators` option and binding it to the instance of `UnambiguousRoleValidator` that was injected into `ActorFormReactiveComponent`.
+In the following example, the `validate` function of `UniqueRoleValidator` is applied to `roleControl` by passing it to the control's `asyncValidators` option and binding it to the instance of `UniqueRoleValidator` that was injected into `ActorFormReactiveComponent`.
The value of `asyncValidators` can be either a single async validator function, or an array of functions.
To learn more about `FormControl` options, see the [AbstractControlOptions](api/forms/AbstractControlOptions) API reference.
@@ -330,7 +330,7 @@ You can delay updating the form validity by changing the `updateOn` property fro
With template-driven forms, set the property in the template.
```angular-html
-
+
```
With reactive forms, set the property in the `FormControl` instance.
diff --git a/adev-ja/src/content/guide/forms/form-validation.md b/adev-ja/src/content/guide/forms/form-validation.md
index 740a7b4bcd..06aca2471e 100644
--- a/adev-ja/src/content/guide/forms/form-validation.md
+++ b/adev-ja/src/content/guide/forms/form-validation.md
@@ -250,9 +250,9 @@ const actorForm = new FormGroup(
次の例は、テンプレート駆動フォームでこれを実現する方法を示しています。
```angular-html
-
+
-@if(model.pending) {
+@if (model.pending) {
}
```
@@ -278,7 +278,7 @@ interface ActorsService {
実際のアプリケーションでは、`ActorsService`は、アクターデータベースにHTTPリクエストを送信して役割が利用可能かどうかを確認する役割を担います。
バリデーターの観点から、サービスの実際の実装は重要でないため、例では`ActorsService`インターフェースに対してのみコードを作成できます。
-検証が始まると、`UnambiguousRoleValidator`は、現在のコントロール値で`ActorsService`の`isRoleTaken()`メソッドに委任します。
+検証が始まると、`UniqueRoleValidator`は、現在のコントロール値で`ActorsService`の`isRoleTaken()`メソッドに委任します。
この時点で、コントロールは`pending`としてマークされ、`validate()`メソッドから返されるObservableチェーンが完了するまで、この状態を維持します。
`isRoleTaken()`メソッドは、役割が利用可能かどうかを確認するHTTPリクエストをディスパッチし、結果として`Observable`を返します。
@@ -300,7 +300,7 @@ interface ActorsService {
次に、バリデーター関数を`FormControl`に直接渡して、適用します。
-次の例では、`UnambiguousRoleValidator`の`validate`関数が、`roleControl`に適用されています。この関数をコントロールの`asyncValidators`オプションに渡し、`ActorFormReactiveComponent`に注入された`UnambiguousRoleValidator`のインスタンスにバインドしています。
+次の例では、`UniqueRoleValidator`の`validate`関数が、`roleControl`に適用されています。この関数をコントロールの`asyncValidators`オプションに渡し、`ActorFormReactiveComponent`に注入された`UniqueRoleValidator`のインスタンスにバインドしています。
`asyncValidators`の値は、単一の非同期バリデーター関数、または関数の配列にできます。
`FormControl`オプションの詳細については、[AbstractControlOptions](api/forms/AbstractControlOptions) APIリファレンスを参照してください。
@@ -330,7 +330,7 @@ interface ActorsService {
テンプレート駆動フォームでは、テンプレートでプロパティを設定します。
```angular-html
-
+
```
リアクティブフォームでは、`FormControl`インスタンスでプロパティを設定します。
diff --git a/adev-ja/src/content/guide/forms/reactive-forms.en.md b/adev-ja/src/content/guide/forms/reactive-forms.en.md
index 5dc6e6c548..cd0474c37f 100644
--- a/adev-ja/src/content/guide/forms/reactive-forms.en.md
+++ b/adev-ja/src/content/guide/forms/reactive-forms.en.md
@@ -387,25 +387,21 @@ You can bind a `FormArray` directly to a `
`,
})
export class FormArrayExampleComponent {
- controls = [
- new FormControl('fish'),
- new FormControl('cat'),
- new FormControl('dog'),
- ];
+ controls = [new FormControl('fish'), new FormControl('cat'), new FormControl('dog')];
form = new FormArray(this.controls);
}
@@ -451,7 +447,7 @@ import {
} from '@angular/forms';
@Component({
- /* ... */
+ /*...*/
})
export class UnifiedEventsBasicComponent {
form = new FormGroup({
@@ -601,7 +597,9 @@ When updating form controls programmatically, you have precise control over how
By default `emitEvent: true`, any change to a control emits events through the `valueChanges` and `statusChanges` observables. Setting `emitEvent: false` suppresses these emissions, which is useful when setting values programmatically without triggering reactive behavior like auto-save, avoiding circular updates between controls, or performing bulk updates where events should emit only once at the end.
```ts
-@Component({/* ... */})
+@Component({
+ /* ... */
+})
export class BlogPostEditor {
postForm = new FormGroup({
title: new FormControl(''),
@@ -610,16 +608,15 @@ export class BlogPostEditor {
constructor() {
// Auto-save draft every time user types
- this.postForm.valueChanges.subscribe(formValue => {
+ this.postForm.valueChanges.subscribe((formValue) => {
this.autosaveDraft(formValue);
});
}
loadExistingDraft(savedDraft: {title: string; content: string}) {
// Restore draft without triggering auto-save
- this.postForm.setValue(savedDraft, { emitEvent: false });
+ this.postForm.setValue(savedDraft, {emitEvent: false});
}
-
}
```
diff --git a/adev-ja/src/content/guide/forms/reactive-forms.md b/adev-ja/src/content/guide/forms/reactive-forms.md
index 4e2fcfbdea..2723766279 100644
--- a/adev-ja/src/content/guide/forms/reactive-forms.md
+++ b/adev-ja/src/content/guide/forms/reactive-forms.md
@@ -18,7 +18,7 @@
テンプレート駆動型フォームでは、テンプレート内の直接アクセスを使用してデータを変更できますが、リアクティブフォームほど明示的ではありません。これは、テンプレートに埋め込まれたディレクティブと、変更を非同期的に追跡するミュータブルデータに依存するためです。
2つのパラダイムの詳細な比較については、[フォームの概要](guide/forms)を参照してください。
-## 基本的なフォームコントロールの追加
+## 基本的なフォームコントロールの追加 {#adding-a-basic-form-control}
フォームコントロールを使用するには、次の3つの手順があります。
@@ -387,25 +387,21 @@ _フォーム検証_ は、ユーザー入力が完全で正しいことを確
これは、フォームがトップレベルの `FormGroup` を使用せず、配列自体が完全なフォームモデルを表す場合に便利です。
```angular-ts
-import { Component } from '@angular/core';
-import { FormArray, FormControl } from '@angular/forms';
+import {Component} from '@angular/core';
+import {FormArray, FormControl} from '@angular/forms';
@Component({
selector: 'form-array-example',
template: `
`,
})
export class FormArrayExampleComponent {
- controls = [
- new FormControl('fish'),
- new FormControl('cat'),
- new FormControl('dog'),
- ];
+ controls = [new FormControl('fish'), new FormControl('cat'), new FormControl('dog')];
form = new FormArray(this.controls);
}
@@ -451,7 +447,7 @@ import {
} from '@angular/forms';
@Component({
- /* ... */
+ /*...*/
})
export class UnifiedEventsBasicComponent {
form = new FormGroup({
@@ -601,7 +597,9 @@ onSubmit() {
デフォルトで `emitEvent: true` の場合、コントロールへの変更は `valueChanges` と `statusChanges` Observableを通じてイベントを発行します。`emitEvent: false` を設定すると、これらの発行が抑制されます。これは、自動保存のようなリアクティブな動作をトリガーせずにプログラムで値を設定する場合、コントロール間の循環更新を回避する場合、またはイベントが最後に一度だけ発行されるべき一括更新を実行する場合に便利です。
```ts
-@Component({/* ... */})
+@Component({
+ /* ... */
+})
export class BlogPostEditor {
postForm = new FormGroup({
title: new FormControl(''),
@@ -610,16 +608,15 @@ export class BlogPostEditor {
constructor() {
// ユーザーが入力するたびに下書きを自動保存
- this.postForm.valueChanges.subscribe(formValue => {
+ this.postForm.valueChanges.subscribe((formValue) => {
this.autosaveDraft(formValue);
});
}
loadExistingDraft(savedDraft: {title: string; content: string}) {
// 自動保存をトリガーせずに下書きを復元
- this.postForm.setValue(savedDraft, { emitEvent: false });
+ this.postForm.setValue(savedDraft, {emitEvent: false});
}
-
}
```
diff --git a/adev-ja/src/content/guide/forms/signals/async-operations.md b/adev-ja/src/content/guide/forms/signals/async-operations.md
new file mode 100644
index 0000000000..ec4a837c2b
--- /dev/null
+++ b/adev-ja/src/content/guide/forms/signals/async-operations.md
@@ -0,0 +1,552 @@
+# Async operations
+
+Some validation requires data from external sources like backend APIs or third-party services. Signal Forms provides two functions for asynchronous validation: `validateHttp()` for HTTP-based validation and `validateAsync()` for custom resource-based validation.
+
+## When to use async validation
+
+Use async validation when your validation logic requires external data. Some common examples include:
+
+- **Uniqueness checks** - Verify usernames or emails don't already exist
+- **Database lookups** - Check values against server-side data
+- **External API validation** - Validate addresses, tax IDs, or other data with third-party services
+- **Server-side business rules** - Apply validation rules that only the server can verify
+
+Don't use async validation for checks you can perform synchronously on the client. Use synchronous validation rules like `pattern()`, `email()`, or `validate()` for format validation and static rules.
+
+## How async validation works
+
+Async validation runs only after all synchronous validation passes. While the validation executes, the field's `pending()` signal returns `true`. The validation can target errors to specific fields, and pending requests cancel automatically when field values change.
+
+Here's an example checking username availability:
+
+```angular-ts
+import {Component, signal} from '@angular/core';
+import {form, validateHttp, FormField} from '@angular/forms/signals';
+
+@Component({
+ selector: 'app-registration',
+ imports: [FormField],
+ template: `
+
+ `,
+})
+export class Registration {
+ registrationModel = signal({username: ''});
+
+ registrationForm = form(this.registrationModel, (schemaPath) => {
+ validateHttp(schemaPath.username, {
+ request: ({value}) => {
+ const username = value();
+ return username ? `/api/users/check?username=${username}` : undefined;
+ },
+ onSuccess: (response) => {
+ return response.available
+ ? null
+ : {
+ kind: 'usernameTaken',
+ message: 'Username is already taken',
+ };
+ },
+ onError: (error) => {
+ console.error('Validation request failed:', error);
+ return {
+ kind: 'serverError',
+ message: 'Could not verify username availability',
+ };
+ },
+ });
+ });
+}
+```
+
+The validation flow works like this:
+
+1. User types a value
+2. Synchronous validation rules run first
+3. If synchronous validation fails, async validation doesn't run
+4. If synchronous validation passes, async validation starts and `pending()` becomes `true`
+5. The request completes and `pending()` becomes `false`
+6. Errors update based on the response
+
+## HTTP validation with validateHttp()
+
+The `validateHttp()` function provides the most common form of async validation. Use it when you need to validate against a REST API or any HTTP endpoint.
+
+### Request function
+
+The `request` function returns either a URL string or an `HttpResourceRequest` object. Return `undefined` to skip the validation:
+
+```ts
+import {Component, signal} from '@angular/core';
+import {form, validateHttp, FormField} from '@angular/forms/signals';
+
+@Component({
+ selector: 'app-registration',
+ imports: [FormField],
+ template: `...`,
+})
+export class Registration {
+ registrationModel = signal({username: ''});
+
+ // Cache usernames that passed validation
+ private validatedUsernames = new Set();
+
+ registrationForm = form(this.registrationModel, (schemaPath) => {
+ validateHttp(schemaPath.username, {
+ request: ({value}) => {
+ const username = value();
+ // Skip HTTP request if already validated
+ if (this.validatedUsernames.has(username)) return undefined;
+
+ return `/api/users/check?username=${username}`;
+ },
+ onSuccess: (response, {value}) => {
+ if (response.available) {
+ // Cache successful validations
+ this.validatedUsernames.add(value());
+ return null;
+ }
+ return {
+ kind: 'usernameTaken',
+ message: 'Username is already taken',
+ };
+ },
+ onError: () => ({
+ kind: 'serverError',
+ message: 'Could not verify username',
+ }),
+ });
+ });
+}
+```
+
+For POST requests or custom headers, return an `HttpResourceRequest` object:
+
+```ts
+request: ({value}) => ({
+ url: '/api/validate',
+ method: 'POST',
+ body: {username: value()},
+}) // prettier-ignore
+```
+
+### Success and error handlers
+
+The `onSuccess` function receives the HTTP response and returns validation errors or `undefined` for valid values:
+
+```ts
+onSuccess: (response) => {
+ if (response.valid) return undefined;
+
+ return {
+ kind: 'invalid',
+ message: response.message || 'Validation failed',
+ };
+} // prettier-ignore
+```
+
+Return multiple errors when needed:
+
+```ts
+onSuccess: (response) => {
+ const errors = [];
+ if (response.usernameTaken) {
+ errors.push({
+ kind: 'usernameTaken',
+ message: 'Username taken',
+ });
+ }
+ if (response.profanity) {
+ errors.push({
+ kind: 'profanity',
+ message: 'Username contains inappropriate content',
+ });
+ }
+ return errors.length > 0 ? errors : undefined;
+} // prettier-ignore
+```
+
+The `onError` function handles request failures like network errors or HTTP errors:
+
+```ts
+onError: (error) => {
+ console.error('Validation request failed:', error);
+ return {
+ kind: 'serverError',
+ message: 'Could not verify. Please try again later.',
+ };
+} // prettier-ignore
+```
+
+### HTTP options
+
+Customize the HTTP request with the `options` parameter:
+
+```ts
+import {HttpHeaders} from '@angular/common/http';
+
+validateHttp(schemaPath.field, {
+ request: ({value}) => `/api/validate?value=${value()}`,
+ options: {
+ headers: new HttpHeaders({
+ Authorization: 'Bearer token',
+ }),
+ timeout: 5000,
+ },
+ onSuccess: (response) =>
+ response.valid
+ ? null
+ : {
+ kind: 'invalid',
+ message: 'Invalid value',
+ },
+ onError: () => ({
+ kind: 'requestFailed',
+ message: 'Unable to reach server to validate.',
+ }),
+});
+```
+
+TIP: See the [httpResource API documentation](api/common/http/httpResource) for all available options.
+
+## Custom async validation with validateAsync()
+
+Most applications should use `validateHttp()` for async validation. It handles HTTP requests with minimal configuration and covers the majority of use cases.
+
+`validateAsync()` is a lower-level API that exposes Angular's resource primitive directly. It offers complete control but requires more code and familiarity with Angular's resource API.
+
+Consider `validateAsync()` only when `validateHttp()` can't meet your needs. Some examples include:
+
+- **Non-HTTP validation** - WebSocket connections, IndexedDB lookups, or Web Worker computations
+- **Custom caching strategies** - Application-specific caching beyond simple memoization
+- **Complex retry logic** - Custom backoff strategies or conditional retries
+- **Direct resource access** - When you need the full resource lifecycle
+
+### Creating a custom validation rule
+
+The `validateAsync()` function requires four properties: `params`, `factory`, `onSuccess`, and `onError`. The `params` function returns the parameters for your resource, while `factory` creates the resource:
+
+```ts
+import {Component, inject, signal, resource, Signal} from '@angular/core';
+import {form, validateAsync, FormField} from '@angular/forms/signals';
+import {UsernameValidator} from './username-validator';
+
+@Component({
+ selector: 'app-registration',
+ imports: [FormField],
+ template: `...`,
+})
+export class Registration {
+ registrationModel = signal({username: ''});
+
+ private usernameValidator = inject(UsernameValidator);
+ private cache = new Map();
+
+ // Custom resource factory with caching
+ createUsernameResource = (usernameSignal: Signal) => {
+ return resource({
+ params: () => usernameSignal(),
+ loader: async ({params: username}) => {
+ if (!username) return undefined;
+
+ // Check cache first
+ const cached = this.cache.get(username);
+ if (cached !== undefined) return cached;
+
+ // Use injected service for validation
+ const result = await this.usernameValidator.checkAvailability(username);
+
+ // Cache result
+ this.cache.set(username, result);
+ return result;
+ },
+ });
+ };
+
+ registrationForm = form(this.registrationModel, (schemaPath) => {
+ validateAsync(schemaPath.username, {
+ params: ({value}) => {
+ const username = value();
+ return username.length >= 3 ? username : undefined;
+ },
+ factory: this.createUsernameResource,
+ onSuccess: (result) => {
+ return result?.available
+ ? null
+ : {
+ kind: 'usernameTaken',
+ message: 'Username taken',
+ };
+ },
+ onError: (error) => {
+ console.error('Validation failed:', error);
+ return {
+ kind: 'serverError',
+ message: 'Could not verify username',
+ };
+ },
+ });
+ });
+}
+```
+
+The `params` function runs on every value change. Return `undefined` to skip validation. The `factory` function runs once during setup and receives params as a signal. The resource updates automatically when params change.
+
+### Using Observable-based services
+
+If your application has existing services that return Observables, use `rxResource` from `@angular/core/rxjs-interop`:
+
+```ts
+import {Component, inject, signal, Signal} from '@angular/core';
+import {rxResource} from '@angular/core/rxjs-interop';
+import {form, validateAsync, FormField} from '@angular/forms/signals';
+import {UsernameService} from './username-service';
+
+@Component({
+ selector: 'app-registration',
+ imports: [FormField],
+ template: `...`,
+})
+export class Registration {
+ registrationModel = signal({username: ''});
+
+ private usernameService = inject(UsernameService);
+
+ private createUsernameResource = (usernameSignal: Signal) => {
+ return rxResource({
+ request: () => usernameSignal(),
+ stream: ({request: username}) => this.usernameService.checkUsername(username),
+ });
+ };
+
+ registrationForm = form(this.registrationModel, (schemaPath) => {
+ validateAsync(schemaPath.username, {
+ params: ({value}) => value() || undefined,
+ factory: this.createUsernameResource,
+ onSuccess: (result) =>
+ result?.available ? null : {kind: 'usernameTaken', message: 'Username taken'},
+ onError: () => ({
+ kind: 'serverError',
+ message: 'Could not verify username',
+ }),
+ });
+ });
+}
+```
+
+The `rxResource` function works directly with Observables and handles subscription cleanup automatically when the field value changes.
+
+## Understanding pending state
+
+When async validation runs, the field's `pending()` signal returns `true`. During this time:
+
+- `valid()` returns `false`
+- `invalid()` returns `false`
+- `errors()` returns an empty array
+- `submit()` waits for validation to complete
+
+Show the pending state in your template to provide feedback:
+
+```angular-html
+
+
+@if (loginForm.username().pending()) {
+ Checking availability...
+}
+
+@if (loginForm.username().touched() && loginForm.username().invalid()) {
+ @for (error of loginForm.username().errors(); track $index) {
+ {{ error.message }}
+ }
+}
+```
+
+Disable form submission while validation is pending:
+
+```angular-html
+
+```
+
+TIP: See the [Field State Management guide](guide/forms/signals/field-state-management) for more patterns using `pending()`, `valid()`, and `invalid()` signals.
+
+### Validation execution order
+
+Async validation only runs after synchronous validation passes. This prevents unnecessary server requests for invalid input:
+
+```ts
+import {form, required, minLength, validateHttp} from '@angular/forms/signals';
+
+form(model, (schemaPath) => {
+ // 1. These synchronous validation rules run first
+ required(schemaPath.username);
+ minLength(schemaPath.username, 3);
+
+ // 2. This async validation rule only runs if synchronous validation passes
+ validateHttp(schemaPath.username, {
+ request: ({value}) => `/api/check?username=${value()}`,
+ onSuccess: (result) =>
+ result.valid
+ ? null
+ : {
+ kind: 'usernameTaken',
+ message: 'Username taken',
+ },
+ onError: () => ({
+ kind: 'serverError',
+ message: 'Validation failed',
+ }),
+ });
+});
+```
+
+This execution order improves performance by reducing server load and catching format errors instantly.
+
+### Request cancellation
+
+When a field value changes, Signal Forms automatically cancels any pending async validation request for that field. This prevents race conditions and ensures validation always reflects the current value. You don't need to implement cancellation logic yourself.
+
+## Best practices
+
+### Combine with synchronous validation
+
+Always validate format before making async requests. This catches errors instantly and prevents unnecessary server requests:
+
+```ts
+import {form, required, email, validateHttp} from '@angular/forms/signals';
+
+form(model, (schemaPath) => {
+ // Validate format first
+ required(schemaPath.email);
+ email(schemaPath.email);
+
+ // Then check availability
+ validateHttp(schemaPath.email, {
+ request: ({value}) => `/api/emails/check?email=${value()}`,
+ onSuccess: (result) =>
+ result.available
+ ? null
+ : {
+ kind: 'emailInUse',
+ message: 'Email already in use',
+ },
+ onError: () => ({
+ kind: 'serverError',
+ message: 'Could not verify email',
+ }),
+ });
+});
+```
+
+### Skip validation when appropriate
+
+Return `undefined` from the `request` function to skip validation. Use this to avoid validating empty fields or values that don't meet minimum requirements:
+
+```ts
+import {validateHttp} from '@angular/forms/signals';
+
+validateHttp(schemaPath.username, {
+ request: ({value}) => {
+ const username = value();
+ // Skip validation for empty or short usernames
+ if (!username || username.length < 3) return undefined;
+
+ return `/api/users/check?username=${username}`;
+ },
+ onSuccess: (result) =>
+ result.valid
+ ? null
+ : {
+ kind: 'usernameTaken',
+ message: 'Username taken',
+ },
+ onError: () => ({
+ kind: 'serverError',
+ message: 'Validation failed',
+ }),
+});
+```
+
+### Handle errors gracefully
+
+Provide clear, user-friendly error messages. Log technical details for debugging but show simple messages to users:
+
+```ts
+import {validateHttp} from '@angular/forms/signals';
+
+validateHttp(schemaPath.field, {
+ request: ({value}) => `/api/validate?field=${value()}`,
+ onSuccess: (result) => {
+ if (result.valid) return null;
+ // Use server message when available
+ return {
+ kind: 'serverError',
+ message: result.message || 'Validation failed',
+ };
+ },
+ onError: (error) => {
+ // Log for debugging
+ console.error('Validation request failed:', error);
+
+ // Show user-friendly message
+ return {
+ kind: 'serverError',
+ message: 'Unable to validate. Please try again later.',
+ };
+ },
+});
+```
+
+### Show clear feedback
+
+Use the `pending()` signal to show when validation is happening. This helps users understand delays and provides better perceived performance:
+
+```angular-html
+@if (field().pending()) {
+
+
+ Checking...
+
+}
+@if (field().valid() && !field().pending()) {
+ Available
+}
+@if (field().invalid()) {
+ {{ field().errors()[0]?.message }}
+}
+```
+
+## Next steps
+
+This guide covered async validation with `validateHttp()` and `validateAsync()`. Related guides explore other aspects of Signal Forms:
+
+
+
+
+
+
+For detailed API documentation, see:
+
+- [`validateHttp()`](api/forms/signals/validateHttp) - HTTP-based async validation
+- [`validateAsync()`](api/forms/signals/validateAsync) - Custom resource-based async validation
+- [`httpResource()`](api/common/http/httpResource) - Angular's HTTP resource API
+- [`resource()`](api/core/resource) - Angular's resource primitive
diff --git a/adev-ja/src/content/guide/forms/signals/custom-controls.en.md b/adev-ja/src/content/guide/forms/signals/custom-controls.en.md
index 163aee9bc6..30df0a45f8 100644
--- a/adev-ja/src/content/guide/forms/signals/custom-controls.en.md
+++ b/adev-ja/src/content/guide/forms/signals/custom-controls.en.md
@@ -4,7 +4,7 @@ NOTE: This guide assumes familiarity with [Signal Forms essentials](essentials/s
The browser's built-in form controls (like input, select, textarea) handle common cases, but applications often need specialized inputs. A date picker with calendar UI, a rich text editor with formatting toolbar, or a tag selector with autocomplete all require custom implementations.
-Signal Forms works with any component that implements specific interfaces. A **control interface** defines the properties and signals that allow your component to communicate with the form system. When your component implements one of these interfaces, the `[field]` directive automatically connects your control to form state, validation, and data binding.
+Signal Forms works with any component that implements specific interfaces. A **control interface** defines the properties and signals that allow your component to communicate with the form system. When your component implements one of these interfaces, the `[formField]` directive automatically connects your control to form state, validation, and data binding.
## Creating a basic custom control
@@ -15,8 +15,8 @@ Let's start with a minimal implementation and add features as needed.
A basic custom input only needs to implement the `FormValueControl` interface and define the required `value` model signal.
```angular-ts
-import { Component, model } from '@angular/core';
-import { FormValueControl } from '@angular/forms/signals';
+import {Component, model} from '@angular/core';
+import {FormValueControl} from '@angular/forms/signals';
@Component({
selector: 'app-basic-input',
@@ -41,21 +41,17 @@ export class BasicInput implements FormValueControl {
A checkbox-style control needs two things:
-1. Implement the `FormCheckboxControl` interface so the `Field` directive will recognize it as a form control
+1. Implement the `FormCheckboxControl` interface so the `FormField` directive will recognize it as a form control
2. Provide a `checked` model signal
```angular-ts
-import { Component, model, ChangeDetectionStrategy } from '@angular/core';
-import { FormCheckboxControl } from '@angular/forms/signals';
+import {Component, model, ChangeDetectionStrategy} from '@angular/core';
+import {FormCheckboxControl} from '@angular/forms/signals';
@Component({
selector: 'app-basic-toggle',
template: `
-