diff --git a/.textlintrc b/.textlintrc
index bf6acfa6e..45af8b558 100644
--- a/.textlintrc
+++ b/.textlintrc
@@ -30,7 +30,8 @@
"が",
"に",
"にも",
- "は"
+ "は",
+ "でも"
]
},
"no-exclamation-question-mark": false,
@@ -40,7 +41,8 @@
"二重中括弧構文",
"変更検知戦略",
"推移的依存関係",
- "三重等号演算子"
+ "三重等号演算子",
+ "入力変換関数"
]
},
"ja-no-mixed-period": false
diff --git a/adev-ja/src/app/features/update/recommendations.en.ts b/adev-ja/src/app/features/update/recommendations.en.ts
index 1d5fe99a9..ccc6fe0e8 100644
--- a/adev-ja/src/app/features/update/recommendations.en.ts
+++ b/adev-ja/src/app/features/update/recommendations.en.ts
@@ -2397,4 +2397,121 @@ export const RECOMMENDATIONS: Step[] = [
action:
'You may experience tests failures if you have tests that rely on change detection execution order when using `ComponentFixture.autoDetect` because it now executes change detection for fixtures within `ApplicationRef.tick`. For example, this will cause test fixture to refresh before any dialogs that it creates whereas this may have been the other way around in the past.',
},
+
+ {
+ action:
+ 'Angular directives, components and pipes are now standalone by default. Specify "standalone: false" for declarations that are currently declared in an NgModule. The Angular CLI will automatically update your code to reflect that.',
+ level: ApplicationComplexity.Basic,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-standalone-declarations',
+ },
+ {
+ action:
+ 'Remove `this.` prefix when accessing template reference variables. For example, refactor `
{{ this.foo }}` to `{{ foo }}`',
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-remove-this',
+ },
+ {
+ action:
+ 'Replace usages of `BrowserModule.withServerTransition()` with injection of the `APP_ID` token to set the application `id` instead.',
+ level: ApplicationComplexity.Basic,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-remove-browser-module-with-server-transition',
+ },
+ {
+ action: 'The `factories` property in `KeyValueDiffers` has been removed.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-remove-key-value-differs-factories',
+ },
+ {
+ action:
+ 'In angular.json, replace the "name" option with "project" for the `@angular/localize` builder.',
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0_localize_builder_project_option',
+ },
+ {
+ action: 'Rename `ExperimentalPendingTasks` to `PendingTasks`.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0_rename_experimental_pending_tasks',
+ },
+ {
+ action:
+ "Update tests that relied on the `Promise` timing of effects to use `await whenStable()` or call `.detectChanges()` to trigger effects. For effects triggered during change detection, ensure they don't depend on the application being fully rendered or consider using `afterRenderEffect()`. Tests using faked clocks may need to fast-forward/flush the clock.",
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0.1',
+ },
+ {
+ action: 'Upgrade to TypeScript version 5.5 or later.',
+ level: ApplicationComplexity.Basic,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0.2',
+ },
+ {
+ action:
+ 'Update tests using `fakeAsync` that rely on specific timing of zone coalescing and scheduling when a change happens outside the Angular zone (hybrid mode scheduling) as these timers are now affected by `tick` and `flush`.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-timers-in-zone',
+ },
+ {
+ action:
+ "When using `createComponent` API and not passing content for the first `ng-content`, provide `document.createTextNode('')` as a `projectableNode` to prevent rendering the default fallback content.",
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-render-default-fallback',
+ },
+ {
+ action:
+ 'Update tests that rely on specific timing or ordering of change detection around custom elements, as the timing may have changed due to the switch to the hybrid scheduler.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-hybrid-scheduler-timing',
+ },
+ {
+ action:
+ 'Migrate from using `Router.errorHandler` to `withNavigationErrorHandler` from `provideRouter` or `errorHandler` from `RouterModule.forRoot`.',
+ level: ApplicationComplexity.Basic,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-router-error-handler',
+ },
+ {
+ action:
+ 'Update tests to handle errors thrown during `ApplicationRef.tick` by either triggering change detection synchronously or rejecting outstanding `ComponentFixture.whenStable` promises.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-testbed-error-handling',
+ },
+ {
+ action: 'Update usages of `Resolve` interface to include `RedirectCommand` in its return type.',
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-update-resolve-interface-return-type',
+ },
+ {
+ action:
+ '`fakeAsync` will flush pending timers by default. For tests that require the previous behavior, explicitly pass `{flush: false}` in the options parameter.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-update-fakeasync-to-flush-pending-timers',
+ },
];
diff --git a/adev-ja/src/app/features/update/recommendations.ts b/adev-ja/src/app/features/update/recommendations.ts
index d1d3c7377..4f98ba291 100644
--- a/adev-ja/src/app/features/update/recommendations.ts
+++ b/adev-ja/src/app/features/update/recommendations.ts
@@ -2397,4 +2397,121 @@ export const RECOMMENDATIONS: Step[] = [
action:
'`ComponentFixture.autoDetect` が `ApplicationRef.tick` 内のフィクスチャの変更検出を実行するようになったため、`ComponentFixture.autoDetect` を使用しているときに変更検出の実行順序に依存しているテストがあると、テストに失敗することがあります。たとえば、これによってテストフィクスチャは、これまではその逆であったかもしれませんが、作成するダイアログの前にリフレッシュされます。',
},
+
+ {
+ action:
+ 'Angular directives, components and pipes are now standalone by default. Specify "standalone: false" for declarations that are currently declared in an NgModule. The Angular CLI will automatically update your code to reflect that.',
+ level: ApplicationComplexity.Basic,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-standalone-declarations',
+ },
+ {
+ action:
+ 'Remove `this.` prefix when accessing template reference variables. For example, refactor `{{ this.foo }}` to `{{ foo }}`',
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-remove-this',
+ },
+ {
+ action:
+ 'Replace usages of `BrowserModule.withServerTransition()` with injection of the `APP_ID` token to set the application `id` instead.',
+ level: ApplicationComplexity.Basic,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-remove-browser-module-with-server-transition',
+ },
+ {
+ action: 'The `factories` property in `KeyValueDiffers` has been removed.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-remove-key-value-differs-factories',
+ },
+ {
+ action:
+ 'In angular.json, replace the "name" option with "project" for the `@angular/localize` builder.',
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0_localize_builder_project_option',
+ },
+ {
+ action: 'Rename `ExperimentalPendingTasks` to `PendingTasks`.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0_rename_experimental_pending_tasks',
+ },
+ {
+ action:
+ "Update tests that relied on the `Promise` timing of effects to use `await whenStable()` or call `.detectChanges()` to trigger effects. For effects triggered during change detection, ensure they don't depend on the application being fully rendered or consider using `afterRenderEffect()`. Tests using faked clocks may need to fast-forward/flush the clock.",
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0.1',
+ },
+ {
+ action: 'Upgrade to TypeScript version 5.5 or later.',
+ level: ApplicationComplexity.Basic,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0.2',
+ },
+ {
+ action:
+ 'Update tests using `fakeAsync` that rely on specific timing of zone coalescing and scheduling when a change happens outside the Angular zone (hybrid mode scheduling) as these timers are now affected by `tick` and `flush`.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-timers-in-zone',
+ },
+ {
+ action:
+ "When using `createComponent` API and not passing content for the first `ng-content`, provide `document.createTextNode('')` as a `projectableNode` to prevent rendering the default fallback content.",
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-render-default-fallback',
+ },
+ {
+ action:
+ 'Update tests that rely on specific timing or ordering of change detection around custom elements, as the timing may have changed due to the switch to the hybrid scheduler.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-hybrid-scheduler-timing',
+ },
+ {
+ action:
+ 'Migrate from using `Router.errorHandler` to `withNavigationErrorHandler` from `provideRouter` or `errorHandler` from `RouterModule.forRoot`.',
+ level: ApplicationComplexity.Basic,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-router-error-handler',
+ },
+ {
+ action:
+ 'Update tests to handle errors thrown during `ApplicationRef.tick` by either triggering change detection synchronously or rejecting outstanding `ComponentFixture.whenStable` promises.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-testbed-error-handling',
+ },
+ {
+ action: 'Update usages of `Resolve` interface to include `RedirectCommand` in its return type.',
+ level: ApplicationComplexity.Medium,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-update-resolve-interface-return-type',
+ },
+ {
+ action:
+ '`fakeAsync` will flush pending timers by default. For tests that require the previous behavior, explicitly pass `{flush: false}` in the options parameter.',
+ level: ApplicationComplexity.Advanced,
+ necessaryAsOf: 1900,
+ possibleIn: 1900,
+ step: '19.0.0-update-fakeasync-to-flush-pending-timers',
+ },
];
diff --git a/adev-ja/src/app/features/update/update.component.en.ts b/adev-ja/src/app/features/update/update.component.en.ts
index 840f859cf..d82843a76 100644
--- a/adev-ja/src/app/features/update/update.component.en.ts
+++ b/adev-ja/src/app/features/update/update.component.en.ts
@@ -56,6 +56,7 @@ export default class AppComponent {
protected afterRecommendations: Step[] = [];
protected readonly versions = [
+ {name: '19.0', number: 1900},
{name: '18.0', number: 1800},
{name: '17.0', number: 1700},
{name: '16.0', number: 1600},
@@ -93,7 +94,7 @@ export default class AppComponent {
];
protected from = this.versions.find((version) => version.name === '17.0')!;
protected to = this.versions.find((version) => version.name === '18.0')!;
- protected futureVersion = 1900;
+ protected futureVersion = 2000;
protected readonly steps: Step[] = RECOMMENDATIONS;
diff --git a/adev-ja/src/app/features/update/update.component.ts b/adev-ja/src/app/features/update/update.component.ts
index ac1a956f8..6ecf6a5d2 100644
--- a/adev-ja/src/app/features/update/update.component.ts
+++ b/adev-ja/src/app/features/update/update.component.ts
@@ -56,6 +56,7 @@ export default class AppComponent {
protected afterRecommendations: Step[] = [];
protected readonly versions = [
+ {name: '19.0', number: 1900},
{name: '18.0', number: 1800},
{name: '17.0', number: 1700},
{name: '16.0', number: 1600},
@@ -93,7 +94,7 @@ export default class AppComponent {
];
protected from = this.versions.find((version) => version.name === '17.0')!;
protected to = this.versions.find((version) => version.name === '18.0')!;
- protected futureVersion = 1900;
+ protected futureVersion = 2000;
protected readonly steps: Step[] = RECOMMENDATIONS;
diff --git a/adev-ja/src/app/sub-navigation-data.en.ts b/adev-ja/src/app/sub-navigation-data.en.ts
index 23a733fb6..cad8b3168 100644
--- a/adev-ja/src/app/sub-navigation-data.en.ts
+++ b/adev-ja/src/app/sub-navigation-data.en.ts
@@ -46,34 +46,24 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'introduction/essentials/overview',
},
{
- label: 'Composing with Components',
+ label: 'Composition with components',
path: 'essentials/components',
contentPath: 'introduction/essentials/components',
},
{
- label: 'Managing Dynamic Data',
- path: 'essentials/managing-dynamic-data',
- contentPath: 'introduction/essentials/managing-dynamic-data',
+ label: 'Reactivity with signals',
+ path: 'essentials/signals',
+ contentPath: 'introduction/essentials/signals',
},
{
- label: 'Rendering Dynamic Templates',
- path: 'essentials/rendering-dynamic-templates',
- contentPath: 'introduction/essentials/rendering-dynamic-templates',
+ label: 'Dynamic interfaces with templates',
+ path: 'essentials/templates',
+ contentPath: 'introduction/essentials/templates',
},
{
- label: 'Conditionals and Loops',
- path: 'essentials/conditionals-and-loops',
- contentPath: 'introduction/essentials/conditionals-and-loops',
- },
- {
- label: 'Handling User Interaction',
- path: 'essentials/handling-user-interaction',
- contentPath: 'introduction/essentials/handling-user-interaction',
- },
- {
- label: 'Sharing Logic',
- path: 'essentials/sharing-logic',
- contentPath: 'introduction/essentials/sharing-logic',
+ label: 'Modular design with dependency injection',
+ path: 'essentials/dependency-injection',
+ contentPath: 'introduction/essentials/dependency-injection',
},
{
label: 'Next Steps',
@@ -91,6 +81,26 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
{
label: 'In-depth Guides',
children: [
+ {
+ label: 'Signals',
+ children: [
+ {
+ label: 'Overview',
+ path: 'guide/signals',
+ contentPath: 'guide/signals/overview',
+ },
+ {
+ label: 'linkedSignal',
+ path: 'guide/signals/linked-signal',
+ contentPath: 'guide/signals/linked-signal',
+ },
+ {
+ label: 'Resource',
+ path: 'guide/signals/resource',
+ contentPath: 'guide/signals/resource',
+ },
+ ],
+ },
{
label: 'Components',
children: [
@@ -99,11 +109,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/components',
contentPath: 'guide/components/anatomy-of-components',
},
- {
- label: 'Importing and using components',
- path: 'guide/components/importing',
- contentPath: 'guide/components/importing',
- },
{
label: 'Selectors',
path: 'guide/components/selectors',
@@ -124,11 +129,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/components/outputs',
contentPath: 'guide/components/outputs',
},
- {
- label: 'output() function',
- path: 'guide/components/output-fn',
- contentPath: 'guide/components/output-function',
- },
{
label: 'Content projection with ng-content',
path: 'guide/components/content-projection',
@@ -269,6 +269,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/directives/directive-composition-api',
contentPath: 'guide/directives/directive-composition-api',
},
+ {
+ label: 'Optimizing images with NgOptimizedImage',
+ path: 'guide/image-optimization',
+ contentPath: 'guide/image-optimization',
+ },
],
},
{
@@ -316,36 +321,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
- {
- label: 'Signals',
- children: [
- {
- label: 'Overview',
- path: 'guide/signals',
- contentPath: 'guide/signals/overview',
- },
- {
- label: 'RxJS Interop',
- path: 'guide/signals/rxjs-interop',
- contentPath: 'guide/signals/rxjs-interop',
- },
- {
- label: 'Inputs as signals',
- path: 'guide/signals/inputs',
- contentPath: 'guide/signals/inputs',
- },
- {
- label: 'Model inputs',
- path: 'guide/signals/model',
- contentPath: 'guide/signals/model',
- },
- {
- label: 'Queries as signals',
- path: 'guide/signals/queries',
- contentPath: 'guide/signals/queries',
- },
- ],
- },
{
label: 'Routing',
children: [
@@ -442,7 +417,7 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
],
},
{
- label: 'Performance',
+ label: 'Server-side & hybrid-rendering',
children: [
{
label: 'Overview',
@@ -450,17 +425,7 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'guide/performance/overview',
},
{
- label: 'Deferrable views',
- path: 'guide/defer',
- contentPath: 'guide/defer',
- },
- {
- label: 'Image Optimization',
- path: 'guide/image-optimization',
- contentPath: 'guide/image-optimization',
- },
- {
- label: 'Server-side Rendering',
+ label: 'Server-side rendering',
path: 'guide/ssr',
contentPath: 'guide/ssr',
},
@@ -469,11 +434,21 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/prerendering',
contentPath: 'guide/prerendering',
},
+ {
+ label: 'Hybrid rendering with server routing',
+ path: 'guide/hybrid-rendering',
+ contentPath: 'guide/hybrid-rendering',
+ },
{
label: 'Hydration',
path: 'guide/hydration',
contentPath: 'guide/hydration',
},
+ {
+ label: 'Incremental Hydration',
+ path: 'guide/incremental-hydration',
+ contentPath: 'guide/incremental-hydration',
+ },
],
},
{
@@ -586,36 +561,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
- {
- label: 'Animations',
- children: [
- {
- label: 'Overview',
- path: 'guide/animations',
- contentPath: 'guide/animations/overview',
- },
- {
- label: 'Transition and Triggers',
- path: 'guide/animations/transition-and-triggers',
- contentPath: 'guide/animations/transition-and-triggers',
- },
- {
- label: 'Complex Sequences',
- path: 'guide/animations/complex-sequences',
- contentPath: 'guide/animations/complex-sequences',
- },
- {
- label: 'Reusable Animations',
- path: 'guide/animations/reusable-animations',
- contentPath: 'guide/animations/reusable-animations',
- },
- {
- label: 'Route transition animations',
- path: 'guide/animations/route-animations',
- contentPath: 'guide/animations/route-animations',
- },
- ],
- },
{
label: 'Experimental features',
children: [
@@ -797,6 +742,56 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
{
label: 'Extended Ecosystem',
children: [
+ {
+ label: 'NgModules',
+ path: 'guide/ngmodules/overview',
+ contentPath: 'guide/ngmodules/overview',
+ },
+ {
+ label: 'Animations',
+ children: [
+ {
+ label: 'Overview',
+ path: 'guide/animations',
+ contentPath: 'guide/animations/overview',
+ },
+ {
+ label: 'Transition and Triggers',
+ path: 'guide/animations/transition-and-triggers',
+ contentPath: 'guide/animations/transition-and-triggers',
+ },
+ {
+ label: 'Complex Sequences',
+ path: 'guide/animations/complex-sequences',
+ contentPath: 'guide/animations/complex-sequences',
+ },
+ {
+ label: 'Reusable Animations',
+ path: 'guide/animations/reusable-animations',
+ contentPath: 'guide/animations/reusable-animations',
+ },
+ {
+ label: 'Route transition animations',
+ path: 'guide/animations/route-animations',
+ contentPath: 'guide/animations/route-animations',
+ },
+ ],
+ },
+ {
+ label: 'Using RxJS with Angular',
+ children: [
+ {
+ label: 'Signals interop',
+ path: 'ecosystem/rxjs-interop',
+ contentPath: 'ecosystem/rxjs-interop/signals-interop',
+ },
+ {
+ label: 'Component output interop',
+ path: 'ecosystem/rxjs-interop/output-interop',
+ contentPath: 'ecosystem/rxjs-interop/output-interop',
+ },
+ ],
+ },
{
label: 'Service Workers & PWAs',
children: [
@@ -1370,6 +1365,11 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'extended-diagnostics/NG8111',
contentPath: 'reference/extended-diagnostics/NG8111',
},
+ {
+ label: 'NG8113: Unused Standalone Imports',
+ path: 'extended-diagnostics/NG8113',
+ contentPath: 'reference/extended-diagnostics/NG8113',
+ },
],
},
{
@@ -1439,80 +1439,15 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'reference/migrations/route-lazy-loading',
contentPath: 'reference/migrations/route-lazy-loading',
},
- ],
- },
- {
- label: 'Concepts',
- children: [
{
- label: 'Overview',
- path: 'reference/concepts',
- contentPath: 'reference/concepts/overview',
+ label: 'Signal inputs',
+ path: 'reference/migrations/signal-inputs',
+ contentPath: 'reference/migrations/signal-inputs',
},
{
- label: 'NgModule',
- children: [
- {
- label: 'Overview',
- path: 'guide/ngmodules',
- contentPath: 'guide/ngmodules/overview',
- },
- {
- label: 'JS Modules vs NgModules',
- path: 'guide/ngmodules/vs-jsmodule',
- contentPath: 'guide/ngmodules/vs-jsmodule',
- },
- {
- label: 'Launching your app with a root module',
- path: 'guide/ngmodules/bootstrapping',
- contentPath: 'guide/ngmodules/bootstrapping',
- },
- {
- label: 'Sharing NgModules',
- path: 'guide/ngmodules/sharing',
- contentPath: 'guide/ngmodules/sharing',
- },
- {
- label: 'Frequently used NgModules',
- path: 'guide/ngmodules/frequent',
- contentPath: 'guide/ngmodules/frequent',
- },
- {
- label: 'Feature modules',
- path: 'guide/ngmodules/feature-modules',
- contentPath: 'guide/ngmodules/feature-modules',
- },
- {
- label: 'Types of feature modules',
- path: 'guide/ngmodules/module-types',
- contentPath: 'guide/ngmodules/module-types',
- },
- {
- label: 'Providing dependencies',
- path: 'guide/ngmodules/providers',
- contentPath: 'guide/ngmodules/providers',
- },
- {
- label: 'Singleton services',
- path: 'guide/ngmodules/singleton-services',
- contentPath: 'guide/ngmodules/singleton-services',
- },
- {
- label: 'Lazy-loading feature modules',
- path: 'guide/ngmodules/lazy-loading',
- contentPath: 'guide/ngmodules/lazy-loading',
- },
- {
- label: 'NgModule API',
- path: 'guide/ngmodules/api',
- contentPath: 'guide/ngmodules/api',
- },
- {
- label: 'NgModule FAQs',
- path: 'guide/ngmodules/faq',
- contentPath: 'guide/ngmodules/faq',
- },
- ],
+ label: 'Signal queries',
+ path: 'reference/migrations/signal-queries',
+ contentPath: 'reference/migrations/signal-queries',
},
],
},
diff --git a/adev-ja/src/app/sub-navigation-data.ts b/adev-ja/src/app/sub-navigation-data.ts
index 93247d21d..cf1859524 100644
--- a/adev-ja/src/app/sub-navigation-data.ts
+++ b/adev-ja/src/app/sub-navigation-data.ts
@@ -11,6 +11,7 @@ import {NavigationItem} from '@angular/docs';
// These 2 imports are expected to be red because they are generated a build time
import FIRST_APP_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/first-app/routes.json';
import LEARN_ANGULAR_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/learn-angular/routes.json';
+import DEFERRABLE_VIEWS_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/deferrable-views/routes.json';
import {DefaultPage} from './core/enums/pages';
import {getApiNavigationItems} from './features/references/helpers/manifest.helper';
@@ -50,29 +51,19 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'introduction/essentials/components',
},
{
- label: '動的なデータの管理',
- path: 'essentials/managing-dynamic-data',
- contentPath: 'introduction/essentials/managing-dynamic-data',
+ label: 'リアクティビティとシグナル',
+ path: 'essentials/signals',
+ contentPath: 'introduction/essentials/signals',
},
{
- label: '動的なテンプレート',
- path: 'essentials/rendering-dynamic-templates',
- contentPath: 'introduction/essentials/rendering-dynamic-templates',
+ label: 'テンプレートによる動的なインターフェース',
+ path: 'essentials/templates',
+ contentPath: 'introduction/essentials/templates',
},
{
- label: '条件分岐とループ',
- path: 'essentials/conditionals-and-loops',
- contentPath: 'introduction/essentials/conditionals-and-loops',
- },
- {
- label: 'ユーザーインタラクションの処理',
- path: 'essentials/handling-user-interaction',
- contentPath: 'introduction/essentials/handling-user-interaction',
- },
- {
- label: 'ロジックの共有',
- path: 'essentials/sharing-logic',
- contentPath: 'introduction/essentials/sharing-logic',
+ label: '依存性の注入によるモジュール設計',
+ path: 'essentials/dependency-injection',
+ contentPath: 'introduction/essentials/dependency-injection',
},
{
label: '次のステップ',
@@ -90,6 +81,26 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
{
label: '詳細ガイド',
children: [
+ {
+ label: 'シグナル',
+ children: [
+ {
+ label: '概要',
+ path: 'guide/signals',
+ contentPath: 'guide/signals/overview',
+ },
+ {
+ label: 'linkedSignal',
+ path: 'guide/signals/linked-signal',
+ contentPath: 'guide/signals/linked-signal',
+ },
+ {
+ label: 'Resource',
+ path: 'guide/signals/resource',
+ contentPath: 'guide/signals/resource',
+ },
+ ],
+ },
{
label: 'コンポーネント',
children: [
@@ -98,11 +109,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/components',
contentPath: 'guide/components/anatomy-of-components',
},
- {
- label: 'コンポーネントのインポートと使用',
- path: 'guide/components/importing',
- contentPath: 'guide/components/importing',
- },
{
label: 'セレクター',
path: 'guide/components/selectors',
@@ -123,11 +129,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/components/outputs',
contentPath: 'guide/components/outputs',
},
- {
- label: 'output()関数',
- path: 'guide/components/output-fn',
- contentPath: 'guide/components/output-function',
- },
{
label: 'ng-contentによるコンテンツ投影',
path: 'guide/components/content-projection',
@@ -268,6 +269,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/directives/directive-composition-api',
contentPath: 'guide/directives/directive-composition-api',
},
+ {
+ label: 'NgOptimizedImageによる画像の最適化',
+ path: 'guide/image-optimization',
+ contentPath: 'guide/image-optimization',
+ },
],
},
{
@@ -315,36 +321,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
- {
- label: 'シグナル',
- children: [
- {
- label: '概要',
- path: 'guide/signals',
- contentPath: 'guide/signals/overview',
- },
- {
- label: 'RxJSとの相互運用',
- path: 'guide/signals/rxjs-interop',
- contentPath: 'guide/signals/rxjs-interop',
- },
- {
- label: '入力としてのシグナル',
- path: 'guide/signals/inputs',
- contentPath: 'guide/signals/inputs',
- },
- {
- label: 'モデル入力',
- path: 'guide/signals/model',
- contentPath: 'guide/signals/model',
- },
- {
- label: 'シグナルによるクエリ',
- path: 'guide/signals/queries',
- contentPath: 'guide/signals/queries',
- },
- ],
- },
{
label: 'ルーティング',
children: [
@@ -441,23 +417,13 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
],
},
{
- label: 'パフォーマンス',
+ label: 'サーバーサイドとハイブリッドレンダリング',
children: [
{
label: '概要',
path: 'guide/performance',
contentPath: 'guide/performance/overview',
},
- {
- label: '遅延可能なビュー',
- path: 'guide/defer',
- contentPath: 'guide/defer',
- },
- {
- label: '画像最適化',
- path: 'guide/image-optimization',
- contentPath: 'guide/image-optimization',
- },
{
label: 'サーバーサイドレンダリング',
path: 'guide/ssr',
@@ -468,11 +434,21 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/prerendering',
contentPath: 'guide/prerendering',
},
+ {
+ label: 'サーバールーティングによるハイブリッドレンダリング',
+ path: 'guide/hybrid-rendering',
+ contentPath: 'guide/hybrid-rendering',
+ },
{
label: 'ハイドレーション',
path: 'guide/hydration',
contentPath: 'guide/hydration',
},
+ {
+ label: 'インクリメンタルハイドレーション',
+ path: 'guide/incremental-hydration',
+ contentPath: 'guide/incremental-hydration',
+ },
],
},
{
@@ -585,36 +561,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
- {
- label: 'アニメーション',
- children: [
- {
- label: '概要',
- path: 'guide/animations',
- contentPath: 'guide/animations/overview',
- },
- {
- label: 'トランジションとトリガー',
- path: 'guide/animations/transition-and-triggers',
- contentPath: 'guide/animations/transition-and-triggers',
- },
- {
- label: '複雑なシーケンス',
- path: 'guide/animations/complex-sequences',
- contentPath: 'guide/animations/complex-sequences',
- },
- {
- label: '再利用可能なアニメーション',
- path: 'guide/animations/reusable-animations',
- contentPath: 'guide/animations/reusable-animations',
- },
- {
- label: 'ルート遷移アニメーション',
- path: 'guide/animations/route-animations',
- contentPath: 'guide/animations/route-animations',
- },
- ],
- },
{
label: '実験的機能',
children: [
@@ -794,8 +740,58 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
],
},
{
- label: '拡張されたエコシステム',
+ label: '拡張エコシステム',
children: [
+ {
+ label: 'NgModule',
+ path: 'guide/ngmodules/overview',
+ contentPath: 'guide/ngmodules/overview',
+ },
+ {
+ label: 'アニメーション',
+ children: [
+ {
+ label: '概要',
+ path: 'guide/animations',
+ contentPath: 'guide/animations/overview',
+ },
+ {
+ label: 'トランジションとトリガー',
+ path: 'guide/animations/transition-and-triggers',
+ contentPath: 'guide/animations/transition-and-triggers',
+ },
+ {
+ label: '複雑なシーケンス',
+ path: 'guide/animations/complex-sequences',
+ contentPath: 'guide/animations/complex-sequences',
+ },
+ {
+ label: '再利用可能なアニメーション',
+ path: 'guide/animations/reusable-animations',
+ contentPath: 'guide/animations/reusable-animations',
+ },
+ {
+ label: 'ルート遷移アニメーション',
+ path: 'guide/animations/route-animations',
+ contentPath: 'guide/animations/route-animations',
+ },
+ ],
+ },
+ {
+ label: 'RxJSとの併用',
+ children: [
+ {
+ label: 'Signalとの相互運用',
+ path: 'ecosystem/rxjs-interop',
+ contentPath: 'ecosystem/rxjs-interop/signals-interop',
+ },
+ {
+ label: 'コンポーネント出力との相互接続',
+ path: 'ecosystem/rxjs-interop/output-interop',
+ contentPath: 'ecosystem/rxjs-interop/output-interop',
+ },
+ ],
+ },
{
label: 'Service WorkerとPWA',
children: [
@@ -872,6 +868,7 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
export const TUTORIALS_SUB_NAVIGATION_DATA: NavigationItem[] = [
FIRST_APP_TUTORIAL_NAV_DATA,
LEARN_ANGULAR_TUTORIAL_NAV_DATA,
+ DEFERRABLE_VIEWS_TUTORIAL_NAV_DATA,
{
path: DefaultPage.TUTORIALS,
contentPath: 'tutorials/home',
@@ -1376,6 +1373,11 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'extended-diagnostics/NG8111',
contentPath: 'reference/extended-diagnostics/NG8111',
},
+ {
+ label: 'NG8113: Unused Standalone Imports',
+ path: 'extended-diagnostics/NG8113',
+ contentPath: 'reference/extended-diagnostics/NG8113',
+ },
],
},
{
@@ -1445,80 +1447,15 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'reference/migrations/route-lazy-loading',
contentPath: 'reference/migrations/route-lazy-loading',
},
- ],
- },
- {
- label: 'コンセプト',
- children: [
{
- label: '概要',
- path: 'reference/concepts',
- contentPath: 'reference/concepts/overview',
+ label: 'Signal inputs',
+ path: 'reference/migrations/signal-inputs',
+ contentPath: 'reference/migrations/signal-inputs',
},
{
- label: 'NgModule',
- children: [
- {
- label: '概要',
- path: 'guide/ngmodules',
- contentPath: 'guide/ngmodules/overview',
- },
- {
- label: 'JS Modules vs NgModules',
- path: 'guide/ngmodules/vs-jsmodule',
- contentPath: 'guide/ngmodules/vs-jsmodule',
- },
- {
- label: 'Launching your app with a root module',
- path: 'guide/ngmodules/bootstrapping',
- contentPath: 'guide/ngmodules/bootstrapping',
- },
- {
- label: 'Sharing NgModules',
- path: 'guide/ngmodules/sharing',
- contentPath: 'guide/ngmodules/sharing',
- },
- {
- label: 'Frequently used NgModules',
- path: 'guide/ngmodules/frequent',
- contentPath: 'guide/ngmodules/frequent',
- },
- {
- label: 'Feature modules',
- path: 'guide/ngmodules/feature-modules',
- contentPath: 'guide/ngmodules/feature-modules',
- },
- {
- label: 'Types of feature modules',
- path: 'guide/ngmodules/module-types',
- contentPath: 'guide/ngmodules/module-types',
- },
- {
- label: 'Providing dependencies',
- path: 'guide/ngmodules/providers',
- contentPath: 'guide/ngmodules/providers',
- },
- {
- label: 'Singleton services',
- path: 'guide/ngmodules/singleton-services',
- contentPath: 'guide/ngmodules/singleton-services',
- },
- {
- label: 'Lazy-loading feature modules',
- path: 'guide/ngmodules/lazy-loading',
- contentPath: 'guide/ngmodules/lazy-loading',
- },
- {
- label: 'NgModule API',
- path: 'guide/ngmodules/api',
- contentPath: 'guide/ngmodules/api',
- },
- {
- label: 'NgModule FAQs',
- path: 'guide/ngmodules/faq',
- contentPath: 'guide/ngmodules/faq',
- },
- ],
+ label: 'Signal queries',
+ path: 'reference/migrations/signal-queries',
+ contentPath: 'reference/migrations/signal-queries',
},
],
},
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 4d80ceaf4..184899457 100644
--- a/adev-ja/src/content/best-practices/style-guide.en.md
+++ b/adev-ja/src/content/best-practices/style-guide.en.md
@@ -293,8 +293,8 @@ Provides a consistent way to quickly identify and reference pipes.
| Symbol name | File name |
|:--- |:--- |
-| @Pipe({ standalone: true, name: 'ellipsis' }) export class EllipsisPipe implements PipeTransform { } | ellipsis.pipe.ts |
-| @Pipe({ standalone: true, name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { } | init-caps.pipe.ts |
+| @Pipe({ name: 'ellipsis' }) export class EllipsisPipe implements PipeTransform { } | ellipsis.pipe.ts |
+| @Pipe({ name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { } | init-caps.pipe.ts |
### Unit test file names
diff --git a/adev-ja/src/content/best-practices/style-guide.md b/adev-ja/src/content/best-practices/style-guide.md
index 9c8ea3fd9..3ebc15bd3 100644
--- a/adev-ja/src/content/best-practices/style-guide.md
+++ b/adev-ja/src/content/best-practices/style-guide.md
@@ -293,8 +293,8 @@ Angular の HTML パーサーは大文字小文字を区別し、アッパーキ
| シンボル名 | ファイル名 |
|:--- |:--- |
-| @Pipe({ standalone: true, name: 'ellipsis' }) export class EllipsisPipe implements PipeTransform { } | ellipsis.pipe.ts |
-| @Pipe({ standalone: true, name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { } | init-caps.pipe.ts |
+| @Pipe({ name: 'ellipsis' }) export class EllipsisPipe implements PipeTransform { } | ellipsis.pipe.ts |
+| @Pipe({ name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { } | init-caps.pipe.ts |
### ユニットテストファイル名
diff --git a/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md b/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md
new file mode 100644
index 000000000..cfe278e81
--- /dev/null
+++ b/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md
@@ -0,0 +1,52 @@
+# RxJS interop with component and dirctive outputs
+
+IMPORTANT: The RxJS Interop package is available for [developer preview](reference/releases#developer-preview). It's ready for you to try, but it might change before it is stable.
+
+Tip: This guide assumes you're familiar with [component and directive outputs](guide/components/outputs).
+
+The `@angular/rxjs-interop` package offers two APIs related to component and directive outputs.
+
+## Creating an output based on an RxJs Observable
+
+The `outputFromObservable` lets you create a component or directive output that emits based on an RxJS observable:
+
+
+import {Directive} from '@angular/core';
+import {outputFromObservable} from '@angular/core/rxjs-interop';
+
+@Directive({/*...*/})
+class Draggable {
+ pointerMoves$: Observable = listenToPointerMoves();
+
+ // Whenever `pointerMoves$` emits, the `pointerMove` event fires.
+ pointerMove = outputFromObservable(this.pointerMoves$);
+}
+
+
+The `outputFromObservable` function has special meaning to the Angular compiler. **You may only call `outputFromObservable` in component and directive property initializers.**
+
+When you `subscribe` to the output, Angular automatically forwards the subscription to the underlying observable. Angular stops forwarding values when the component or directive is destroyed.
+
+HELPFUL: Consider using `output()` directly if you can emit values imperatively.
+
+## Creating an RxJS Observable from a component or directive output
+
+The `outputToObservable` function lets you create an RxJS observable from a component output.
+
+
+import {outputToObservable} from '@angular/core/rxjs-interop';
+
+@Component(/*...*/)
+class CustomSlider {
+ valueChange = output();
+}
+
+// Instance reference to `CustomSlider`.
+const slider: CustomSlider = createSlider();
+
+outputToObservable(slider.valueChange) // Observable
+ .pipe(...)
+ .subscribe(...);
+
+
+HELPFUL: Consider using the `subscribe` method on `OutputRef` directly if it meets your needs.
diff --git a/adev-ja/src/content/guide/signals/rxjs-interop.en.md b/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md
similarity index 83%
rename from adev-ja/src/content/guide/signals/rxjs-interop.en.md
rename to adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md
index 66132bc61..410507043 100644
--- a/adev-ja/src/content/guide/signals/rxjs-interop.en.md
+++ b/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md
@@ -1,10 +1,10 @@
-# RxJS Interop
+# RxJS interop with Angular signals
IMPORTANT: The RxJS Interop package is available for [developer preview](reference/releases#developer-preview). It's ready for you to try, but it might change before it is stable.
-Angular's `@angular/core/rxjs-interop` package provides useful utilities to integrate [Angular Signals](guide/signals) with RxJS Observables.
+The `@angular/rxjs-interop` package offers APIs that help you integrate RxJS and Angular signals.
-## `toSignal`
+## Create a signal from an RxJs Observable with `toSignal`
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.
@@ -63,7 +63,7 @@ If an Observable used in `toSignal` produces an error, that error is thrown when
If an Observable used in `toSignal` completes, the signal continues to return the most recently emitted value before completion.
-## `toObservable`
+## Create an RxJS Observale from a signal with `toObservable`
Use the `toObservable` utility to create an `Observable` which tracks the value of a signal. The signal's value is monitored with an `effect` which emits the value to the Observable when it changes.
@@ -103,29 +103,3 @@ mySignal.set(3);
```
Here, only the last value (3) will be logged.
-
-### `outputFromObservable`
-
-`outputFromObservable(...)` declares an Angular output that emits values based on an RxJS observable.
-
-```ts
-class MyDir {
- nameChange$ = new Observable(/* ... */);
- nameChange = outputFromObservable(this.nameChange$); // OutputRef
-}
-```
-
-See more details in the [output() API guide](/guide/components/output-fn).
-
-### `outputToObservable`
-
-`outputToObservable(...)` converts an Angular output to an observable.
-This allows you to integrate Angular outputs conveniently into RxJS streams.
-
-```ts
-outputToObservable(myComp.instance.onNameChange)
- .pipe(...)
- .subscribe(...)
-```
-
-See more details in the [output() API guide](/guide/components/output-fn).
diff --git a/adev-ja/src/content/ecosystem/service-workers/config.md b/adev-ja/src/content/ecosystem/service-workers/config.md
index da5239f6a..a4d16eea2 100644
--- a/adev-ja/src/content/ecosystem/service-workers/config.md
+++ b/adev-ja/src/content/ecosystem/service-workers/config.md
@@ -197,6 +197,7 @@ export interface DataGroup {
maxSize: number;
maxAge: string;
timeout?: string;
+ refreshAhead?: string;
strategy?: 'freshness' | 'performance';
};
cacheQueryOptions?: {
@@ -270,6 +271,22 @@ The network timeout is how long the Angular service worker waits for the network
For example, the string `5s30u` translates to five seconds and 30 milliseconds of network timeout.
+
+##### `refreshAhead`
+
+This duration string specifies the time ahead of the expiration of a cached resource when the Angular service worker should proactively attempt to refresh the resource from the network.
+The `refreshAhead` duration is an optional configuration that determines how much time before the expiration of a cached response the service worker should initiate a request to refresh the resource from the network.
+
+| Suffixes | Details |
+|:--- |:--- |
+| `d` | Days |
+| `h` | Hours |
+| `m` | Minutes |
+| `s` | Seconds |
+| `u` | Milliseconds |
+
+For example, the string `1h30m` translates to one hour and 30 minutes ahead of the expiration time.
+
##### `strategy`
The Angular service worker can use either of two caching strategies for data resources.
@@ -330,7 +347,7 @@ A request is considered to be a navigation request if:
* The URL must not contain a file extension (that is, a `.`) in the last path segment
* The URL must not contain `__`
-HELPFUL: To configure whether navigation requests are sent through to the network or not, see the [navigationRequestStrategy](#navigationrequeststrategy) section.
+HELPFUL: To configure whether navigation requests are sent through to the network or not, see the [navigationRequestStrategy](#navigationrequeststrategy) section and [applicationMaxAge](#application-max-age) sections.
#### Matching navigation request URLs
@@ -374,3 +391,7 @@ This optional property enables you to configure how the service worker handles n
| `'freshness'` | Passes the requests through to the network and falls back to the `performance` behavior when offline. This value is useful when the server redirects the navigation requests elsewhere using a `3xx` HTTP redirect status code. Reasons for using this value include:
Redirecting to an authentication website when authentication is not handled by the application
Redirecting specific URLs to avoid breaking existing links/bookmarks after a website redesign
Redirecting to a different website, such as a server-status page, while a page is temporarily down
|
IMPORTANT: The `freshness` strategy usually results in more requests sent to the server, which can increase response latency. It is recommended that you use the default performance strategy whenever possible.
+
+### `applicationMaxAge`
+
+This optional property enables you to configure how long the service worker will cache any requests. Within the `maxAge`, files will be served from cache. Beyond it, all requests will only be served from the network, including asset and data requests.
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 c26d74939..5aa2f664d 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
@@ -19,7 +19,7 @@ You provide Angular-specific information for a component by adding a `@Component
export class ProfilePhoto { }
-For full details on writing Angular templates, see the [Templates guide](guide/templates).
+For full details on writing Angular templates, including data binding, event handling, and control flow, see the [Templates guide](guide/templates).
The object passed to the `@Component` decorator is called the component's **metadata**. This includes the `selector`, `template`, and other properties described throughout this guide.
@@ -53,6 +53,29 @@ Both `templateUrl` and `styleUrl` are relative to the directory in which the com
## Using components
+### Imports in the `@Component` decorator
+
+To use a component, [directive](guide/directives), or [pipe](guide/templates/pipes), you must add
+it to the `imports` array in the `@Component` decorator:
+
+```angular-ts
+import {ProfilePhoto} from './profile-photo';
+
+@Component({
+ // Import the `ProfilePhoto` component in
+ // order to use it in this component's template.
+ imports: [ProfilePhoto],
+ /* ... */
+})
+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 `NgMdoule` in which the component is defined. See the full [`NgModule` guide](guide/ngmodules) for details.
+
+Important: In Angular versions before 19.0.0, the `standalone` option defaults to `false`.
+
+### Showing components in a template
+
Every component defines a [CSS selector](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors):
@@ -65,21 +88,21 @@ export class ProfilePhoto { }
See [Component Selectors](guide/components/selectors) for details about which types of selectors Angular supports and guidance on choosing a selector.
-You use a component by creating a matching HTML element in the template of _other_ components:
+You show a component by creating a matching HTML element in the template of _other_ components:
-
+
@Component({
- selector: 'user-profile',
- template: `
-
- `,
- ...,
+ selector: 'profile-photo',
+})
+export class ProfilePhoto { }
+
+@Component({
+ imports: [ProfilePhoto],
+ template: ``
})
export class UserProfile { }
-See [Importing and using components](guide/components/importing) for details on how to reference and use other components in your template.
-
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.
The DOM rendered by a component, corresponding to that component's template, is called that
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 6c2e4fbb1..9b2b3522e 100644
--- a/adev-ja/src/content/guide/components/anatomy-of-components.md
+++ b/adev-ja/src/content/guide/components/anatomy-of-components.md
@@ -19,7 +19,7 @@ TypeScriptクラスの上部に `@Component` [デコレーター](https://www.ty
export class ProfilePhoto { }
-Angularテンプレートの書き方については、[テンプレートガイド](guide/templates)を参照してください。
+データバインディング、イベント処理、制御フローなど、Angularテンプレート作成に関する詳細は、[テンプレートガイド](guide/templates)を参照してください。
`@Component` デコレーターに渡されるオブジェクトは、コンポーネントの**メタデータ**と呼ばれます。これには、このガイドで説明されている `selector`、`template`、その他のプロパティが含まれています。
@@ -36,7 +36,7 @@ export class ProfilePhoto { }
デフォルトでは、コンポーネントのスタイルは、そのコンポーネントのテンプレートで定義された要素にのみ影響を与えます。Angularのスタイリングアプローチの詳細については、[コンポーネントのスタイリング](guide/components/styling)を参照してください。
-代わりに、テンプレートとスタイルを別々のファイルに書くこともできます。
+テンプレートとスタイルを別々のファイルに記述することもできます。
@Component({
@@ -47,12 +47,35 @@ export class ProfilePhoto { }
export class ProfilePhoto { }
-これにより、プロジェクト内の*プレゼンテーション*と*動作*の懸念を分離できます。プロジェクト全体で一貫したアプローチを選択することも、コンポーネントごとに使用するものを決定できます。
+これにより、プロジェクト内の_表示_と_動作_の懸念事項を分離できます。プロジェクト全体に対して1つのアプローチを選択するか、コンポーネントごとにどちらを使用するかを決定できます。
-`templateUrl` と `styleUrl` はどちらも、コンポーネントが存在するディレクトリを基準とした相対パスです。
+`templateUrl`と`styleUrl`の両方は、コンポーネントが存在するディレクトリを基準とした相対パスです。
## コンポーネントの使用
+### `@Component`デコレーターでのインポート
+
+コンポーネント、[ディレクティブ](guide/directives)、または[パイプ](guide/templates/pipes)を使用するには、
+`@Component`デコレーターの`imports`配列に追加する必要があります。
+
+```angular-ts
+import {ProfilePhoto} from './profile-photo';
+
+@Component({
+ // このコンポーネントのテンプレートで使用するために、
+ // `ProfilePhoto`コンポーネントをインポートします。
+ imports: [ProfilePhoto],
+ /* ... */
+})
+export class UserProfile { }
+```
+
+デフォルトでは、Angularコンポーネントは*スタンドアロン*です。つまり、他のコンポーネントの`imports`配列に直接追加できます。以前のバージョンのAngularで作成されたコンポーネントは、代わりに`@Component`デコレーターで`standalone: false`を指定している場合があります。これらのコンポーネントの場合、代わりにコンポーネントが定義されている`NgModule`をインポートします。詳細は、完全な[`NgModule`ガイド](guide/ngmodules)を参照してください。
+
+IMPORTANT: 19.0.0より前のAngularバージョンでは、`standalone`オプションはデフォルトで`false`です。
+
+### テンプレートでのコンポーネントの表示
+
すべてのコンポーネントは[CSSセレクター](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors)を定義します。
@@ -63,29 +86,29 @@ export class ProfilePhoto { }
export class ProfilePhoto { }
-Angularがサポートするセレクターの種類と、セレクターを選択する際のガイダンスについては、[コンポーネントセレクター](guide/components/selectors)を参照してください。
+Angularがサポートするセレクターの種類と、セレクターの選択に関するガイダンスについては、[コンポーネントセレクター](guide/components/selectors)を参照してください。
-他のコンポーネントのテンプレートに一致するHTML要素を作成することで、コンポーネントを使用します。
+_他の_コンポーネントのテンプレートで一致するHTML要素を作成することで、コンポーネントを表示します。
-
+
@Component({
- selector: 'user-profile',
- template: `
-
- `,
- ...,
+ selector: 'profile-photo',
+})
+export class ProfilePhoto { }
+
+@Component({
+ imports: [ProfilePhoto],
+ template: ``
})
export class UserProfile { }
-テンプレートで他のコンポーネントを参照して使用する方法は、[コンポーネントのインポートと使用](guide/components/importing)を参照してください。
-
-Angularは、遭遇した一致するHTML要素ごとに、コンポーネントのインスタンスを作成します。コンポーネントのセレクターに一致するDOM要素は、そのコンポーネントの**ホスト要素**と呼ばれます。コンポーネントのテンプレートの内容は、そのホスト要素内にレンダリングされます。
+Angularは、遭遇する一致するHTML要素ごとにコンポーネントのインスタンスを作成します。コンポーネントのセレクターと一致するDOM要素は、そのコンポーネントの**ホスト要素**と呼ばれます。コンポーネントのテンプレートの内容はそのホスト要素内にレンダリングされます。
-コンポーネントによってレンダリングされたDOM (コンポーネントのテンプレートに対応)は、
+コンポーネントによってレンダリングされるDOM(コンポーネントのテンプレートに対応)は、
そのコンポーネントの**ビュー**と呼ばれます。
-このようにコンポーネントを組み合わせることで、**Angular アプリケーションはコンポーネントのツリーとして考えることができます**。
+このようにコンポーネントを構成することで、**Angularアプリケーションをコンポーネントのツリーと考えることができます**。
```mermaid
flowchart TD
@@ -99,4 +122,4 @@ flowchart TD
```
-このツリー構造は、[依存性の注入](guide/di)や[子クエリ](guide/components/queries)など、その他のAngularの概念を理解する上で重要です。
+このツリー構造は、[依存性の注入](guide/di)や[子クエリ](guide/components/queries)など、他のいくつかのAngularの概念を理解する上で重要です。
diff --git a/adev-ja/src/content/guide/components/content-projection.en.md b/adev-ja/src/content/guide/components/content-projection.en.md
index a91950897..59895427b 100644
--- a/adev-ja/src/content/guide/components/content-projection.en.md
+++ b/adev-ja/src/content/guide/components/content-projection.en.md
@@ -148,6 +148,38 @@ did not match a `select` attribute:
If a component does not include an `` placeholder without a `select` attribute, any
elements that don't match one of the component's placeholders do not render into the DOM.
+## Fallback content
+
+Angular can show *fallback content* for a component's `` placeholder if that component doesn't have any matching child content. You can specify fallback content by adding child content to the `` element itself.
+
+```angular-html
+
+
+
+```
+
## 投影のためのコンテンツのエイリアシング
-Angularは、任意の要素にCSSセレクターを指定できる特殊な属性 `ngProjectAs` をサポートしています。
-`ngProjectAs` を持つ要素が `` プレースホルダーに対してチェックされると、
-Angularは要素のIDではなく `ngProjectAs` の値と比較します。
+Angularは、任意の要素にCSSセレクターを指定できる特殊な属性`ngProjectAs`をサポートしています。
+`ngProjectAs`を持つ要素が``プレースホルダーに対してチェックされると、
+Angularは要素のIDではなく`ngProjectAs`の値と比較します。
```angular-html
@@ -182,4 +215,4 @@ Angularは要素のIDではなく `ngProjectAs` の値と比較します。
```
-`ngProjectAs` は静的な値のみをサポートし、動的な式にはバインドできません。
+`ngProjectAs`は静的な値のみをサポートし、動的な式にはバインドできません。
diff --git a/adev-ja/src/content/guide/components/importing.en.md b/adev-ja/src/content/guide/components/importing.en.md
deleted file mode 100644
index 7978df771..000000000
--- a/adev-ja/src/content/guide/components/importing.en.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Importing and using components
-
-Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
-
-Angular supports two ways of making a component available to other components: as a standalone component or in an `NgModule`.
-
-## Standalone components
-
-A **standalone component** is a component that sets `standalone: true` in its component metadata.
-Standalone components directly import other components, directives, and pipes used in their
-templates:
-
-
-@Component({
- standalone: true,
- selector: 'profile-photo',
-})
-export class ProfilePhoto { }
-
-@Component({
- standalone: true,
- imports: [ProfilePhoto],
- template: ``
-})
-export class UserProfile { }
-
-
-Standalone components are directly importable into other standalone components.
-
-The Angular team recommends using standalone components for all new development.
-
-## NgModules
-
-Angular code that predates standalone components uses `NgModule` as a mechanism for importing and
-using other components. See the full [`NgModule` guide](guide/ngmodules) for details.
diff --git a/adev-ja/src/content/guide/components/importing.md b/adev-ja/src/content/guide/components/importing.md
deleted file mode 100644
index 3587bbf2d..000000000
--- a/adev-ja/src/content/guide/components/importing.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# コンポーネントのインポートと使用
-
-Tip: このガイドでは、すでに[基本概念のガイド](essentials)を読んでいることを前提としています。Angularを初めて使用する場合は、まずそちらをお読みください。
-
-Angularでは、他のコンポーネントでコンポーネントを使用可能にするために、2つの方法がサポートされています。スタンドアロンコンポーネントとして、または `NgModule` で。
-
-## スタンドアロンコンポーネント
-
-**スタンドアロンコンポーネント** は、コンポーネントメタデータで `standalone: true` を設定したコンポーネントです。
-スタンドアロンコンポーネントは、テンプレートで使用されている他のコンポーネント、
-ディレクティブ、パイプを直接インポートします。
-
-
-@Component({
- standalone: true,
- selector: 'profile-photo',
-})
-export class ProfilePhoto { }
-
-@Component({
- standalone: true,
- imports:[ProfilePhoto],
- template: ``
-})
-export class UserProfile { }
-
-
-スタンドアロンコンポーネントは、他のスタンドアロンコンポーネントに直接インポートできます。
-
-Angularチームでは、新規開発にはスタンドアロンコンポーネントを使用することを推奨しています。
-
-## NgModules
-
-スタンドアロンコンポーネントが導入される前のAngularコードでは、`NgModule` を使用して、他のコンポーネントをインポートし、使用していました。
-詳細については、[`NgModule` ガイド](guide/ngmodules) を参照してください。
diff --git a/adev-ja/src/content/guide/components/inputs.en.md b/adev-ja/src/content/guide/components/inputs.en.md
index 164c673ca..2ca91966c 100644
--- a/adev-ja/src/content/guide/components/inputs.en.md
+++ b/adev-ja/src/content/guide/components/inputs.en.md
@@ -4,12 +4,16 @@ Tip: This guide assumes you've already read the [Essentials Guide](essentials).
Tip: If you're familiar with other web frameworks, input properties are similar to _props_.
-When creating a component, you can mark specific class properties as **bindable** by adding the `@Input` decorator on the property:
+When you use a component, you commonly want to pass some data to it. A component specifies the data that it accepts by declaring
+**inputs**:
-
-@Component({...})
+
+import {Component, input} from '@angular/core';
+
+@Component({/*...*/})
export class CustomSlider {
- @Input() value = 0;
+ // Declare an input named 'value' with a default value of zero.
+ value = input(0);
}
@@ -19,30 +23,74 @@ This lets you bind to the property in a template:
```
-Angular refers to properties marked with the `@Input` decorator as **inputs**. When using a component, you pass data to it by setting its inputs.
+If an input has a default value, TypeScript infers the type from the default value:
+
+```typescript
+@Component({/*...*/})
+export class CustomSlider {
+ // TypeScript infers that this input is a number, returning InputSignal.
+ value = input(0);
+}
+```
+
+You can explicitly declare a type for the input by specifying a generic parameter to the function.
+
+If an input without a default value is not set, its value is `undefined`:
+
+```typescript
+@Component({/*...*/})
+export class CustomSlider {
+ // Produces an InputSignal because `value` may not be set.
+ value = input();
+}
+```
**Angular records inputs statically at compile-time**. Inputs cannot be added or removed at run-time.
+The `input` function has special meaning to the Angular compiler. **You can exclusively call `input` in component and directive property initializers.**
+
When extending a component class, **inputs are inherited by the child class.**
**Input names are case-sensitive.**
-## Customizing inputs
+## Reading inputs
-The `@Input` decorator accepts a config object that lets you change the way that input works.
+The `input` function returns an `InputSignal`. You can read the value by calling the signal:
-### Required inputs
+
+import {Component, input} from '@angular/core';
-You can specify the `required` option to enforce that a given input must always have a value.
+@Component({/*...*/})
+export class CustomSlider {
+ // Declare an input named 'value' with a default value of zero.
+ value = input(0);
+
+ // Create a computed expression that reads the value input
+ label = computed(() => `The slider's value is ${this.value()}`);
+}
+
+
+Signals created by the `input` function are read-only.
+
+## Required inputs
+
+You can declare that an input is `required` by calling `input.required` instead of `input`:
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Input({required: true}) value = 0;
+ // Declare a required input named value. Returns an `InputSignal`.
+ value = input.required();
}
-If you try to use a component without specifying all of its required inputs, Angular reports an error at build-time.
+Angular enforces that required inputs _must_ be set when the component is used in a template. If you try to use a component without specifying all of its required inputs, Angular reports an error at build-time.
+
+Required inputs do not automatically include `undefined` in the generic parameter of the returned `InputSignal`.
+
+## Configuring inputs
+
+The `input` function accepts a config object as a second parameter that lets you change the way that input works.
### Input transforms
@@ -51,13 +99,13 @@ You can specify a `transform` function to change the value of an input when it's
@Component({
selector: 'custom-slider',
- ...
+ /*...*/
})
export class CustomSlider {
- @Input({transform: trimString}) label = '';
+ label = input('', {transform: trimString});
}
-function trimString(value: string | undefined) {
+function trimString(value: string | undefined): string {
return value?.trim() ?? '';
}
@@ -72,41 +120,41 @@ The most common use-case for input transforms is to accept a wider range of valu
**Input transform function must be statically analyzable at build-time.** You cannot set transform functions conditionally or as the result of an expression evaluation.
-**Input transform functions should always be [pure functions](https://en.wikipedia.org/wiki/Pure_function).** Relying on state outside of the transform function can lead to unpredictable behavior.
+**Input transform functions should always be [pure functions](https://en.wikipedia.org/wiki/Pure_function).** Relying on state outside the transform function can lead to unpredictable behavior.
#### Type checking
When you specify an input transform, the type of the transform function's parameter determines the types of values that can be set to the input in a template.
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Input({transform: appendPx}) widthPx: string = '';
+ widthPx = input('', {transform: appendPx});
}
-function appendPx(value: number) {
+function appendPx(value: number): string {
return `${value}px`;
}
-In the example above, the `widthPx` input accepts a `number` while the property on the class is a `string`.
+In the example above, the `widthPx` input accepts a `number` while the `InputSignal` property returns a `string`.
#### Built-in transformations
Angular includes two built-in transform functions for the two most common scenarios: coercing values to boolean and numbers.
-import {Component, Input, booleanAttribute, numberAttribute} from '@angular/core';
+import {Component, input, booleanAttribute, numberAttribute} from '@angular/core';
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Input({transform: booleanAttribute}) disabled = false;
- @Input({transform: numberAttribute}) number = 0;
+ disabled = input(false, {transform: booleanAttribute});
+ value = input(0, {transform: numberAttribute});
}
-`booleanAttribute` imitates the behavior of standard
-HTML [boolean attributes](https://developer.mozilla.org/docs/Glossary/Boolean/HTML), where the _presence_ of the attribute indicates a "true" value. However, Angular's `booleanAttribute` treats the literal string `"false"` as the boolean `false`.
+`booleanAttribute` imitates the behavior of standard HTML [boolean attributes](https://developer.mozilla.org/docs/Glossary/Boolean/HTML), where the
+_presence_ of the attribute indicates a "true" value. However, Angular's `booleanAttribute` treats the literal string `"false"` as the boolean `false`.
`numberAttribute` attempts to parse the given value to a number, producing `NaN` if parsing fails.
@@ -115,9 +163,9 @@ HTML [boolean attributes](https://developer.mozilla.org/docs/Glossary/Boolean/HT
You can specify the `alias` option to change the name of an input in templates.
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Input({alias: 'sliderValue'}) value = 0;
+ value = input(0, {alias: 'sliderValue'});
}
@@ -129,11 +177,170 @@ This alias does not affect usage of the property in TypeScript code.
While you should generally avoid aliasing inputs for components, this feature can be useful for renaming properties while preserving an alias for the original name or for avoiding collisions with the name of native DOM element properties.
+## Model inputs
+
+**Model inputs** are a special type of input that enable a component to propagate new values back to its parent component.
+
+When creating a component, you can define a model input similarly to how you create a standard input.
+
+Both types of input allow someone to bind a value into the property. However, **model inputs allow the component author to write values into the property**. If the property is bound with a two-way binding, the new value propagates to that binding.
+
+```typescript
+@Component({ /* ... */})
+export class CustomSlider {
+ // Define a model input named "value".
+ value = model(0);
+
+ increment() {
+ // Update the model input with a new value, propagating the value to any bindings.
+ this.value.update(oldValue => oldValue + 10);
+ }
+}
+
+@Component({
+ /* ... */
+ // Using the two-way binding syntax means that any changes to the slider's
+ // value automatically propagate back to the `volume` signal.
+ // Note that this binding uses the signal *instance*, not the signal value.
+ template: ``,
+})
+export class MediaControls {
+ // Create a writable signal for the `volume` local state.
+ volume = signal(0);
+}
+```
+
+In the above example, the `CustomSlider` can write values into its `value` model input, which then propagates those values back to the `volume` signal in `MediaControls`. This binding keeps the values of `value` and `volume` in sync. Notice that the binding passes the `volume` signal instance, not the _value_ of the signal.
+
+In other respects, model inputs work similarly to standard inputs. You can read the value by calling the signal function, including in reactive contexts like `computed` and `effect`.
+
+See [Two-way binding](guide/templates/two-way-binding) for more details on two-way binding in templates.
+
+### Two-way binding with plain properties
+
+You can bind a plain JavaScript property to a model input.
+
+```angular-ts
+@Component({
+ /* ... */
+ // `value` is a model input.
+ // The parenthesis-inside-square-brackets syntax (aka "banana-in-a-box") creates a two-way binding
+ template: '',
+})
+export class MediaControls {
+ protected volume = 0;
+}
+```
+
+In the example above, the `CustomSlider` can write values into its `checked` model input, which then propagates those values back to the `isAdmin` property in `UserProfile`. This binding keeps that values of `checked` and `isAdmin` in sync.
+
+### Implicit `change` events
+
+When you declare a model input in a component or directive, Angular automatically creates a corresponding [output](guide/components/outputs) for that model. The output's name is the model input's name suffixed with "Change".
+
+```angular-ts
+@Directive({ /* ... */ })
+export class CustomCheckbox {
+ // This automatically creates an output named "checkedChange".
+ // Can be subscribed to using `(checkedChange)="handler()"` in the template.
+ checked = model(false);
+}
+```
+
+Angular emits this change event whenever you write a new value into the model input by calling its `set` or `update` methods.
+
+See [Custom events with outputs](guide/components/outputs) for more details on outputs.
+
+### Customizing model inputs
+
+You can mark a model input as required or provide an alias in the same way as a [standard input](guide/signals/inputs).
+
+Model inputs do not support input transforms.
+
+### When to use model inputs
+
+Use model inputs when you want a component to support two-way binding. This is typically appropriate when a component exists to modify a value based on user interaction. Most commonly, custom form controls, such as a date picker or combobox, should use model inputs for their primary value.
+
+## Choosing input names
+
+Avoid choosing input names that collide with properties on DOM elements like HTMLElement. Name collisions introduce confusion about whether the bound property belongs to the component or the DOM element.
+
+Avoid adding prefixes for component inputs like you would with component selectors. Since a given element can only host one component, any custom properties can be assumed to belong to the component.
+
+## Declaring inputs with the `@Input` decorator
+
+Tip: While the Angular team recommends using the signal-based `input` function for new projects, the original decorator-based `@Input` API remains fully supported.
+
+You can alternatively declare component inputs by adding the `@Input` decorator to a property:
+
+
+@Component({...})
+export class CustomSlider {
+ @Input() value = 0;
+}
+
+
+Binding to an input is the same in both signal-based and decorator-based inputs:
+
+```angular-html
+
+```
+
+### Customizing decorator-based inputs
+
+The `@Input` decorator accepts a config object that lets you change the way that input works.
+
+#### Required inputs
+
+You can specify the `required` option to enforce that a given input must always have a value.
+
+
+@Component({...})
+export class CustomSlider {
+ @Input({required: true}) value = 0;
+}
+
+
+If you try to use a component without specifying all of its required inputs, Angular reports an error at build-time.
+
+#### Input transforms
+
+You can specify a `transform` function to change the value of an input when it's set by Angular. This transform function works identically to transform functions for signal-based inputs described above.
+
+
+@Component({
+ selector: 'custom-slider',
+ ...
+})
+export class CustomSlider {
+ @Input({transform: trimString}) label = '';
+}
+
+function trimString(value: string | undefined) { return value?.trim() ?? ''; }
+
+
+#### Input aliases
+
+You can specify the `alias` option to change the name of an input in templates.
+
+
+@Component({...})
+export class CustomSlider {
+ @Input({alias: 'sliderValue'}) value = 0;
+}
+
+
+```angular-html
+
+```
+
The `@Input` decorator also accepts the alias as its first parameter in place of the config object.
-## Inputs with getters and setters
+Input aliases work the same way as for signal-based inputs described above.
+
+### Inputs with getters and setters
-A property implemented with a getter and setter can be an input:
+When using decorator-based inputs, a property implemented with a getter and setter can be an input:
export class CustomSlider {
@@ -142,12 +349,9 @@ export class CustomSlider {
return this.internalValue;
}
- set value(newValue: number) {
- this.internalValue = newValue;
- }
+set value(newValue: number) { this.internalValue = newValue; }
- private internalValue = 0;
-}
+private internalValue = 0; }
You can even create a _write-only_ input by only defining a public setter:
@@ -159,11 +363,10 @@ export class CustomSlider {
this.internalValue = newValue;
}
- private internalValue = 0;
-}
+private internalValue = 0; }
-Prefer using input transforms instead of getters and setters if possible.
+**Prefer using input transforms instead of getters and setters** if possible.
Avoid complex or costly getters and setters. Angular may invoke an input's setter multiple times, which may negatively impact application performance if the setter performs any costly behaviors, such as DOM manipulation.
@@ -190,9 +393,3 @@ You can additionally specify an input alias in the `inputs` list by putting the
})
export class CustomSlider extends BaseSlider { }
-
-## Choosing input names
-
-Avoid choosing input names that collide with properties on DOM elements like HTMLElement. Name collisions introduce confusion about whether the bound property belongs to the component or the DOM element.
-
-Avoid adding prefixes for component inputs like you would with component selectors. Since a given element can only host one component, any custom properties can be assumed to belong to the component.
diff --git a/adev-ja/src/content/guide/components/inputs.md b/adev-ja/src/content/guide/components/inputs.md
index 26fec0277..e11b470f3 100644
--- a/adev-ja/src/content/guide/components/inputs.md
+++ b/adev-ja/src/content/guide/components/inputs.md
@@ -1,63 +1,111 @@
-# 入力プロパティでデータを受け取る
+# 入力プロパティによるデータの受け取り
-Tip: このガイドは、[基本概念のガイド](essentials) を既読していることを前提としています。Angularを初めて使う場合は、まずそちらをお読みください。
+TIP: このガイドは、既に[基本概念ガイド](essentials)を読んでいることを前提としています。Angularを初めて使用する場合は、まずそちらをお読みください。
-Tip: 他のウェブフレームワークに精通している場合は、入力プロパティは*props*に似ています。
+TIP: 他のウェブフレームワークに精通している場合は、入力プロパティは_props_に似ています。
-コンポーネントを作成する際、特定のクラスプロパティに `@Input` デコレーターを追加することで、そのプロパティを **バインド可能** にできます。
+コンポーネントを使用する際に、一般的にいくつかのデータを渡したいことがあります。
+コンポーネントは、**入力**を宣言することで、受け入れるデータを指定します。
-
-@Component({...})
+
+import {Component, input} from '@angular/core';
+
+@Component({/*...*/})
export class CustomSlider {
- @Input() value = 0;
+ // Declare an input named 'value' with a default value of zero.
+ value = input(0);
}
-これにより、テンプレートでプロパティにバインドできます。
+これにより、テンプレートのプロパティにバインドできます。
```angular-html
```
-Angularは、`@Input` デコレーターでマークされたプロパティを **入力** と呼びます。コンポーネントを使用する際、入力に値を設定することでコンポーネントにデータを渡します。
+入力にデフォルト値がある場合、TypeScriptはデフォルト値から型を推論します。
+
+```typescript
+@Component({/*...*/})
+export class CustomSlider {
+ // TypeScriptは、この入力が数値であると推論し、InputSignalを返します。
+ value = input(0);
+}
+```
+
+関数のジェネリックパラメーターを指定することで、入力の型を明示的に宣言できます。
-**Angular はコンパイル時に静的に入力を記録します。** 入力は、実行時に追加または削除はできません。
+デフォルト値のない入力が設定されていない場合、その値は`undefined`になります。
+
+```typescript
+@Component({/*...*/})
+export class CustomSlider {
+ // `value`は設定されない可能性があるため、InputSignalを生成します。
+ value = input();
+}
+```
+
+**Angularはコンパイル時に静的に入力を記録します。**実行時に入力の追加や削除はできません。
+
+`input`関数は、Angularコンパイラにとって特別な意味を持ちます。**`input`は、コンポーネントとディレクティブのプロパティ初期化子でのみ呼び出すことができます。**
コンポーネントクラスを拡張する場合、**入力は子クラスによって継承されます。**
-**入力名は、大文字と小文字が区別されます。**
+**入力名は大文字と小文字が区別されます。**
+
+## 入力の読み取り
+
+`input`関数は`InputSignal`を返します。シグナルを呼び出すことで値を読み取ることができます。
-## 入力のカスタマイズ
+
+import {Component, input} from '@angular/core';
-`@Input` デコレーターは、入力の動作を変更できる設定オブジェクトを受け取ります。
+@Component({/*...*/})
+export class CustomSlider {
+ // Declare an input named 'value' with a default value of zero.
+ value = input(0);
+
+ // Create a computed expression that reads the value input
+ label = computed(() => `The slider's value is ${this.value()}`);
+}
+
+
+`input`関数によって作成されたシグナルは読み取り専用です。
-### 必須入力
+## 必須入力
-`required` オプションを指定することで、特定の入力に常に値が設定されていることを強制できます。
+`input`の代わりに`input.required`を呼び出すことで、入力が`required`であることを宣言できます。
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Input({required: true}) value = 0;
+ // Declare a required input named value. Returns an `InputSignal`.
+ value = input.required();
}
-必須入力をすべて指定せずにコンポーネントを使用しようとすると、Angularはビルド時にエラーを報告します。
+Angularは、テンプレートでコンポーネントを使用する際に、必須入力が_必ず_設定されていることを強制します。すべての必須入力を指定せずにコンポーネントを使用しようとすると、Angularはビルド時にエラーを報告します。
+
+必須入力は、返される`InputSignal`のジェネリックパラメーターに`undefined`を自動的に含めません。
+
+## 入力の構成
+
+`input`関数は、入力の動作を変更できる2番目のパラメーターとしてconfigオブジェクトを受け取ります。
### 入力変換
-`transform` 関数を指定することで、Angularによって入力値が設定されるときに、入力値を変更できます。
+入力がAngularによって設定されるときに、その値を変更する`transform`関数を指定できます。
@Component({
selector: 'custom-slider',
- ...
+ /*...*/
})
export class CustomSlider {
- @Input({transform: trimString}) label = '';
+ label = input('', {transform: trimString});
}
-function trimString(value: string | undefined) {
+function trimString(value: string | undefined): string {
return value?.trim() ?? '';
}
@@ -66,58 +114,58 @@ function trimString(value: string | undefined) {
```
-上記の例では、`systemVolume` の値が変更されるたびに、Angularは `trimString` を実行し、`label` に結果を設定します。
+上記の例では、`systemVolume`の値が変更されるたびに、Angularは`trimString`を実行し、`label`に結果を設定します。
-入力変換の最も一般的なユースケースは、テンプレートでより幅広い値の種類(多くの場合、`null` や `undefined` を含む)を受け入れることです。
+入力変換の最も一般的なユースケースは、テンプレートでより広い範囲の値型を受け入れることであり、多くの場合`null`と`undefined`を含みます。
-**入力変換の関数は、ビルド時に静的に解析可能である必要があります。** 変換関数を条件付きで設定したり、式評価の結果として設定したりできません。
+**入力変換関数は、ビルド時に静的に分析可能でなければなりません。**条件付きで、または式の評価の結果として、変換関数は設定できません。
-**入力変換の関数は、常に [純粋関数](https://en.wikipedia.org/wiki/Pure_function) である必要があります。** 変換関数の外の状態に依存すると、予期しない動作につながる可能性があります。
+**入力変換関数は常に[純粋関数](https://en.wikipedia.org/wiki/Pure_function)でなければなりません。**変換関数外の状態に依存すると、予期せぬ動作につながる可能性があります。
#### 型チェック
-入力変換を指定すると、変換関数のパラメーターの型によって、テンプレートで入力に設定できる値の型が決まります。
+入力変換を指定すると、変換関数の引数の型によって、テンプレートで入力に設定できる値の型が決まります。
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Input({transform: appendPx}) widthPx: string = '';
+ widthPx = input('', {transform: appendPx});
}
-function appendPx(value: number) {
+function appendPx(value: number): string {
return `${value}px`;
}
-上記の例では、`widthPx` 入力値は `number` を受け取りますが、クラスのプロパティは `string` です。
+上記の例では、`widthPx`入力は`number`を受け入れる一方、`InputSignal`プロパティは`string`を返します。
#### 組み込み変換
-Angularには、最も一般的な2つのシナリオに対応する2つの組み込み変換関数が含まれています。ブール値と数値への値の強制変換です。
+Angularには、最も一般的な2つのシナリオのための2つの組み込み変換関数が含まれています。ブール値と数値への値の強制変換です。
-import {Component, Input, booleanAttribute, numberAttribute} from '@angular/core';
+import {Component, input, booleanAttribute, numberAttribute} from '@angular/core';
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Input({transform: booleanAttribute}) disabled = false;
- @Input({transform: numberAttribute}) number = 0;
+ disabled = input(false, {transform: booleanAttribute});
+ value = input(0, {transform: numberAttribute});
}
-`booleanAttribute` は、標準のHTML [ブール属性](https://developer.mozilla.org/docs/Glossary/Boolean/HTML) の動作を模倣します。
-属性の存在は "true" 値を示します。ただし、Angularの `booleanAttribute` は、リテラル文字列 `"false"` をブール値 `false` として扱います。
+`booleanAttribute`は、属性の_存在_が「true」値を示す標準的なHTML[ブール属性](https://developer.mozilla.org/docs/Glossary/Boolean/HTML)の動作を模倣します。
+ただし、Angularの`booleanAttribute`は、リテラル文字列`"false"`をブール値`false`として扱います。
-`numberAttribute` は、指定された値を数値に解析しようとします。解析に失敗すると、`NaN` を生成します。
+`numberAttribute`は、与えられた値を数値として解析しようと試み、解析に失敗した場合は`NaN`を生成します。
### 入力エイリアス
-`alias` オプションを指定することで、テンプレートでの入力の名前を変更できます。
+`alias`オプションを指定して、テンプレートでの入力の名前を変更できます。
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Input({alias: 'sliderValue'}) value = 0;
+ value = input(0, {alias: 'sliderValue'});
}
@@ -127,13 +175,172 @@ export class CustomSlider {
このエイリアスは、TypeScriptコードでのプロパティの使用には影響しません。
-一般的にコンポーネントの入力にエイリアスを使用することは避けるべきですが、この機能はプロパティの名前を変更しながら元の名前のエイリアスを保持する場合や、ネイティブDOM要素プロパティの名前との衝突を避ける場合に役立ちます。
+一般的にコンポーネントの入力をエイリアス化することは避けるべきですが、この機能は、元の名前のエイリアスを保持しながらプロパティの名前を変更したり、ネイティブDOM要素プロパティの名前との競合を回避したりする場合に役立ちます。
+
+## モデル入力
+
+**モデル入力**は、コンポーネントが新しい値を親コンポーネントに伝播できるようにする特殊なタイプの入力です。
+
+コンポーネントを作成する際に、通常の入力と同様にモデル入力を定義できます。
+
+どちらの種類の入力も、値をプロパティにバインドすることを可能にします。しかし、**モデル入力は、コンポーネントの作者がプロパティに値を書き込むことを可能にします。**プロパティが双方向バインディングでバインドされている場合、新しい値はそのバインディングに伝播します。
+
+```typescript
+@Component({ /* ... */})
+export class CustomSlider {
+ // "value"という名前のモデル入力を定義します。
+ value = model(0);
+
+ increment() {
+ // 新しい値でモデル入力を更新し、値をすべてのバインディングに伝播します。
+ this.value.update(oldValue => oldValue + 10);
+ }
+}
+
+@Component({
+ /* ... */
+ // 双方向バインディング構文を使用すると、スライダーの値の変更は、
+ // `volume`シグナルに自動的に伝播します。
+ // このバインディングは、シグナルの値ではなく、シグナルのインスタンスを使用していることに注意してください。
+ template: ``,
+})
+export class MediaControls {
+ // `volume`ローカル状態の書き込み可能なシグナルを作成します。
+ volume = signal(0);
+}
+```
+
+上記の例では、`CustomSlider`は`value`モデル入力に値を書き込むことができ、それによって`MediaControls`の`volume`シグナルに値が伝播します。このバインディングにより、`value`と`volume`の値が同期します。バインディングはシグナルの_値_ではなく、`volume`シグナルのインスタンスを渡していることに注意してください。
+
+他の点では、モデル入力は標準入力と同様に機能します。`computed`や`effect`のようなリアクティブなコンテキスト内を含め、シグナル関数を呼び出すことで値を読み取ることができます。
+
+テンプレートでの双方向バインディングの詳細については、[双方向バインディング](guide/templates/two-way-binding)を参照してください。
+
+### プレーンプロパティとの双方向バインディング
+
+プレーンなJavaScriptプロパティをモデル入力にバインドできます。
+
+```angular-ts
+@Component({
+ /* ... */
+ // `value`はモデル入力です。
+ // 角かっこ内のかっこ記法(別名「バナナインアボックス」)は、双方向バインディングを作成します
+ template: '',
+})
+export class MediaControls {
+ protected volume = 0;
+}
+```
+
+上記の例では、`CustomSlider`は`checked`モデル入力に値を書き込むことができ、それによって`UserProfile`の`isAdmin`プロパティに値が伝播します。このバインディングにより、`checked`と`isAdmin`の値が同期します。
+
+### 暗黙的な`change`イベント
+
+コンポーネントまたはディレクティブでモデル入力を宣言すると、Angularはそのモデルに対応する[出力](guide/components/outputs)を自動的に作成します。出力の名前は、モデル入力の名前に「Change」が付いたものです。
+
+```angular-ts
+@Directive({ /* ... */ })
+export class CustomCheckbox {
+ // これにより、「checkedChange」という名前の出力が自動的に作成されます。
+ // テンプレートで `(checkedChange)="handler()"` を使用して購読できます。
+ checked = model(false);
+}
+```
+
+`set`メソッドまたは`update`メソッドを呼び出すことで、モデル入力に新しい値を書き込むたびに、Angularはこの変更イベントを発生させます。
+
+出力の詳細については、[出力によるカスタムイベント](guide/components/outputs)を参照してください。
+
+### モデル入力のカスタマイズ
+
+[通常の入力](guide/signals/inputs)と同様に、モデル入力を必須としてマークしたり、エイリアスを提供したりできます。
+
+モデル入力は入力変換をサポートしません。
-`@Input` デコレーターは、設定オブジェクトの代わりにエイリアスを最初の引数として受け取ります。
+### モデル入力を使用する場合
-## ゲッターとセッターを使用した入力
+コンポーネントが双方向バインディングをサポートする場合に、モデル入力を使用します。これは通常、ユーザーの操作に基づいて値を変更するためにコンポーネントが存在する場合に適しています。最も一般的には、日付ピッカーやコンボボックスなどのカスタムフォームコントロールは、主要な値にモデル入力を使用する必要があります。
-ゲッターとセッターを使用して実装されたプロパティは、入力にできます。
+# 入力名の選択
+
+DOM要素のプロパティ(HTMLElementなど)と競合する入力名を選択することは避けてください。名前の競合は、バインドされたプロパティがコンポーネントのものであるか、DOM要素のものであるかについて混乱を招きます。
+
+コンポーネントセレクターのように、コンポーネント入力にプレフィックスを追加することは避けてください。特定の要素は1つのコンポーネントしかホストできないため、カスタムプロパティはすべてコンポーネントに属すると見なすことができます。
+
+# `@Input`デコレーターによる入力の宣言
+
+TIP: Angularチームは新しいプロジェクトにはシグナルベースの`input`関数の使用を推奨していますが、元のデコレーターベースの`@Input` APIは引き続き完全にサポートされています。
+
+コンポーネント入力を宣言する代わりに、プロパティに`@Input`デコレーターを追加できます。
+
+
+@Component({...})
+export class CustomSlider {
+ @Input() value = 0;
+}
+
+
+入力へのバインディングは、シグナルベースの入力とデコレーターベースの入力の両方で同じです。
+
+```angular-html
+
+```
+
+### デコレーターベースの入力のカスタマイズ
+
+`@Input`デコレーターは、入力の動作を変更できるconfigオブジェクトを受け取ります。
+
+#### 必須入力
+
+`required`オプションを指定して、特定の入力が常に値を持つ必要があることを強制できます。
+
+
+@Component({...})
+export class CustomSlider {
+ @Input({required: true}) value = 0;
+}
+
+
+すべての必須入力を指定せずにコンポーネントを使用しようとすると、Angularはビルド時にエラーを報告します。
+
+#### 入力変換
+
+Angularによって入力が設定されるときにその値を変更する`transform`関数を指定できます。この変換関数は、上記で説明したシグナルベースの入力の変換関数と同様に機能します。
+
+
+@Component({
+ selector: 'custom-slider',
+ ...
+})
+export class CustomSlider {
+ @Input({transform: trimString}) label = '';
+}
+
+function trimString(value: string | undefined) { return value?.trim() ?? ''; }
+
+
+#### 入力エイリアス
+
+`alias`オプションを指定して、テンプレートでの入力の名前を変更できます。
+
+
+@Component({...})
+export class CustomSlider {
+ @Input({alias: 'sliderValue'}) value = 0;
+}
+
+
+```angular-html
+
+```
+
+`@Input`デコレーターは、configオブジェクトの代わりに、エイリアスを最初のパラメーターとして受け取ります。
+
+入力エイリアスは、上記で説明したシグナルベースの入力と同じように機能します。
+
+### ゲッターとセッターを持つ入力
+
+デコレーターベースの入力を使用する場合、ゲッターとセッターで実装されたプロパティを入力にできます。
export class CustomSlider {
@@ -142,15 +349,12 @@ export class CustomSlider {
return this.internalValue;
}
- set value(newValue: number) {
- this.internalValue = newValue;
- }
+set value(newValue: number) { this.internalValue = newValue; }
- private internalValue = 0;
-}
+private internalValue = 0; }
-公開セッターのみを定義することで、*書き込み専用*の入力を作成できます。
+パブリックセッターのみを定義することで、_書き込み専用_の入力を作成できます。
export class CustomSlider {
@@ -159,20 +363,19 @@ export class CustomSlider {
this.internalValue = newValue;
}
- private internalValue = 0;
-}
+private internalValue = 0; }
-可能な場合は、ゲッターとセッターの代わりに 入力変換 を使用することをお勧めします。
+可能な場合は、**ゲッターとセッターの代わりに入力変換を使用することをお勧めします。**
-複雑なゲッターやセッターは避けてください。Angularは、入力のセッターを複数回呼び出す場合があります。セッターがDOM操作などのコストのかかる動作をする場合、アプリケーションのパフォーマンスに悪影響を及ぼす可能性があります。
+複雑なゲッターとセッター、またはコストの高いゲッターとセッターは避けてください。Angularは入力のセッターを複数回呼び出す可能性があり、セッターがDOM操作などのコストの高い処理を実行する場合、アプリケーションのパフォーマンスに悪影響を与える可能性があります。
-## `@Component` デコレーターで入力を指定する
+## `@Component`デコレーターでの入力の指定
-`@Input` デコレーターに加えて、`@Component` デコレーターの `inputs` プロパティでコンポーネントの入力を指定できます。これは、コンポーネントが基本クラスからプロパティを継承する場合に役立ちます。
+`@Input`デコレーターに加えて、`@Component`デコレーターの`inputs`プロパティを使用して、コンポーネントの入力を指定できます。これは、コンポーネントが基本クラスからプロパティを継承する場合に役立ちます。
-// `CustomSlider` は、`BaseSlider` から `disabled` プロパティを継承します。
+// `CustomSlider` inherits the `disabled` property from `BaseSlider`.
@Component({
...,
inputs: ['disabled'],
@@ -180,19 +383,13 @@ export class CustomSlider {
export class CustomSlider extends BaseSlider { }
-さらに、`inputs` リストで入力エイリアスを指定できます。エイリアスをコロンの後に文字列に記述します。
+文字列の後にコロンを付けてエイリアスを`inputs`リストに指定できます。
-// `CustomSlider` は、`BaseSlider` から `disabled` プロパティを継承します。
+// `CustomSlider` inherits the `disabled` property from `BaseSlider`.
@Component({
...,
inputs: ['disabled: sliderDisabled'],
})
export class CustomSlider extends BaseSlider { }
-
-## 入力名の選択
-
-DOM要素(HTMLElementなど)のプロパティと衝突する入力名は避けてください。名前の衝突は、バインドされたプロパティがコンポーネントに属しているのか、DOM要素に属しているのか混乱を生じさせます。
-
-コンポーネントセレクターのように、コンポーネント入力にプレフィックスを追加することは避けてください。特定の要素は、1つのコンポーネントしかホストできないため、カスタムプロパティはすべてコンポーネントに属すると見なすことができます。
diff --git a/adev-ja/src/content/guide/components/output-function.en.md b/adev-ja/src/content/guide/components/output-function.en.md
deleted file mode 100644
index 9840eaab5..000000000
--- a/adev-ja/src/content/guide/components/output-function.en.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# Function-based outputs
-
-The `output()` function declares an output in a directive or component.
-Outputs allow you to emit values to parent components.
-
-HELPFUL: The `output()` function is currently in [developer preview](/reference/releases#developer-preview).
-
-
-import {Component, output} from '@angular/core';
-
-@Component({...})
-export class MyComp {
- nameChange = output() // OutputEmitterRef
-
- setNewName(newName: string) {
- this.nameChange.emit(newName);
- }
-}
-
-
-An output is automatically recognized by Angular whenever you use the `output` function as an initializer of a class member.
-Parent components can listen to outputs in templates by using the event binding syntax.
-
-```angular-html
-
-```
-
-## Aliasing an output
-
-Angular uses the class member name as the name of the output.
-You can alias outputs to change their public name to be different.
-
-```typescript
-class MyComp {
- nameChange = output({alias: 'ngxNameChange'});
-}
-```
-
-This allows users to bind to your output using `(ngxNameChange)`, while inside your component you can access the output emitter using `this.nameChange`.
-
-## Subscribing programmatically
-
-Consumers may create your component dynamically with a reference to a `ComponentRef`.
-In those cases, parents can subscribe to outputs by directly accessing the property of type `OutputRef`.
-
-```ts
-const myComp = viewContainerRef.createComponent(...);
-
-myComp.instance.nameChange.subscribe(newName => {
- console.log(newName);
-});
-```
-
-Angular will automatically clean up the subscription when `myComp` is destroyed.
-Alternatively, an object with a function to explicitly unsubscribe earlier is returned.
-
-## Using RxJS observables as source
-
-In some cases, you may want to emit output values based on RxJS observables.
-Angular provides a way to use RxJS observables as source for outputs.
-
-The `outputFromObservable` function is a compiler primitive, similar to the `output()` function, and declares outputs that are driven by RxJS observables.
-
-
-import {Directive} from '@angular/core';
-import {outputFromObservable} from '@angular/core/rxjs-interop';
-
-@Directive(...)
-class MyDir {
- nameChange$ = this.dataService.get(); // Observable
- nameChange = outputFromObservable(this.nameChange$);
-}
-
-
-Angular will forward subscriptions to the observable, but will stop forwarding values when the owning directive is destroyed.
-In the example above, if `MyDir` is destroyed, `nameChange` will no longer emit values.
-
-HELPFUL: Most of the time, using `output()` is sufficient and you can emit values imperatively.
-
-## Converting an output to an observable
-
-You can subscribe to outputs by calling `.subscribe` method on `OutputRef`.
-In other cases, Angular provides a helper function that converts an `OutputRef` to an observable.
-
-
-import {outputToObservable} from '@angular/core/rxjs-interop';
-
-@Component(...)
-class MyComp {
- nameChange = output();
-}
-
-// Instance reference to `MyComp`.
-const myComp: MyComp;
-
-outputToObservable(this.myComp.instance.nameChange) // Observable
- .pipe(...)
- .subscribe(...);
-
-
-## Why you should use `output()` over decorator-based `@Output()`?
-
-The `output()` function provides numerous benefits over decorator-based `@Output` and `EventEmitter`:
-
-1. Simpler mental model and API:
- • No concept of error channel, completion channels, or other APIs from RxJS.
- • Outputs are simple emitters. You can emit values using the `.emit` function.
-2. More accurate types.
- • `OutputEmitterRef.emit(value)` is now correctly typed, while `EventEmitter` has broken types and can cause runtime errors.
diff --git a/adev-ja/src/content/guide/components/output-function.md b/adev-ja/src/content/guide/components/output-function.md
deleted file mode 100644
index add6e588d..000000000
--- a/adev-ja/src/content/guide/components/output-function.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# 関数ベースの出力
-
-`output()` 関数は、ディレクティブまたはコンポーネントで出力を宣言します。
-出力を使用すると、親コンポーネントに出力を送信できます。
-
-HELPFUL: `output()` 関数は現在、[開発プレビュー](/reference/releases#developer-preview)です。
-
-
-import {Component, output} from '@angular/core';
-
-@Component({...})
-export class MyComp {
- nameChange = output() // OutputEmitterRef
-
- setNewName(newName: string) {
- this.nameChange.emit(newName);
- }
-}
-
-
-出力は、`output` 関数をクラスメンバーのイニシャライザーとして使用すると、Angularによって自動的に認識されます。
-親コンポーネントは、イベントバインディング構文を使用して、テンプレート内の出力を購読できます。
-
-```angular-html
-
-```
-
-## 出力のエイリアス
-
-Angularは、クラスメンバーの名前を出力の名前として使用します。
-出力にエイリアスを付けることで、公開名を変更できます。
-
-```typescript
-class MyComp {
- nameChange = output({alias: 'ngxNameChange'});
-}
-```
-
-これにより、ユーザーは `(ngxNameChange)` を使用して出力にバインドできます。コンポーネント内では、`this.nameChange` を使用して出力エミッターにアクセスできます。
-
-## プログラムによる購読
-
-コンシューマーは、`ComponentRef` への参照を使用して、コンポーネントを動的に作成できます。
-そのような場合、親は `OutputRef` タイプのプロパティに直接アクセスすることで出力に購読できます。
-
-```ts
-const myComp = viewContainerRef.createComponent(...);
-
-myComp.instance.nameChange.subscribe(newName => {
- console.log(newName);
-});
-```
-
-`myComp` が破棄されると、Angularは自動的に購読をクリーンアップします。
-または、より早く購読を解除するための関数を含むオブジェクトが返されます。
-
-## RxJS Observableをソースとして使用
-
-場合によっては、RxJS Observableに基づいて出力値を送信したいことがあります。
-Angularは、RxJS Observableをアウトプットのソースとして使用する方法を提供します。
-
-`outputFromObservable` 関数は、`output()` 関数と同様にコンパイラのプリミティブであり、RxJS Observableによって駆動される出力を宣言します。
-
-
-import {Directive} from '@angular/core';
-import {outputFromObservable} from '@angular/core/rxjs-interop';
-
-@Directive(...)
-class MyDir {
- nameChange$ = this.dataService.get(); // Observable
- nameChange = outputFromObservable(this.nameChange$);
-}
-
-
-AngularはObservableへの購読を転送しますが、所有するディレクティブが破棄されると値の転送を停止します。
-上記の例では、`MyDir` が破棄されると、`nameChange` は値を送信しなくなります。
-
-HELPFUL: ほとんどの場合、`output()` を使用すれば十分で、値を命令的に送信できます。
-
-## 出力をObservableに変換する
-
-`OutputRef` の `.subscribe` メソッドを呼び出すことで、出力に購読できます。
-他のケースでは、Angularは `OutputRef` をObservableに変換するヘルパー関数を提供します。
-
-
-import {outputToObservable} from '@angular/core/rxjs-interop';
-
-@Component(...)
-class MyComp {
- nameChange = output();
-}
-
-// `MyComp` へのインスタンス参照。
-const myComp: MyComp;
-
-outputToObservable(this.myComp.instance.nameChange) // Observable
- .pipe(...)
- .subscribe(...);
-
-
-## なぜデコレーターベースの `@Output()` よりも `output()` を使用する必要があるのか?
-
-`output()` 関数は、デコレーターベースの `@Output` と `EventEmitter` に比べて、多くの利点があります。
-
-1. よりシンプルなメンタルモデルとAPI:
- • RxJSのエラーチャネル、完了チャネル、またはその他のAPIの概念はありません。
- • 出力は単純なエミッターです。 `.emit` 関数を使用して値を送信できます。
-2. より正確な型。
- • `OutputEmitterRef.emit(value)` は、正しく型付けされていますが、`EventEmitter` の型は壊れており、ランタイムエラーが発生する可能性があります。
diff --git a/adev-ja/src/content/guide/components/outputs.en.md b/adev-ja/src/content/guide/components/outputs.en.md
index 140cb1971..4d910cd6a 100644
--- a/adev-ja/src/content/guide/components/outputs.en.md
+++ b/adev-ja/src/content/guide/components/outputs.en.md
@@ -2,12 +2,12 @@
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
-Angular components can define custom events by assigning a property to a new `EventEmitter` and adding the `@Output` decorator:
+Angular components can define custom events by assigning a property to the `output` function:
-
-@Component({...})
+
+@Component({/*...*/})
export class ExpandablePanel {
- @Output() panelClosed = new EventEmitter();
+ panelClosed = output();
}
@@ -15,13 +15,13 @@ export class ExpandablePanel {
```
-You can emit an event by calling the `emit` method on the `EventEmitter`:
+The `output` function returns an `OutputEmitterRef`. You can emit an event by calling the `emit` method on the `OutputEmitterRef`:
this.panelClosed.emit();
-Angular refers to properties marked with the `@Output` decorator as **outputs**. You can use outputs to pass data to other components, similar to native browser events like `click`.
+Angular refers to properties initialized with the `output` function as **outputs**. You can use outputs to raise custom events, similar to native browser events like `click`.
**Angular custom events do not bubble up the DOM**.
@@ -29,6 +29,8 @@ Angular refers to properties marked with the `@Output` decorator as **outputs**.
When extending a component class, **outputs are inherited by the child class.**
+The `output` function has special meaning to the Angular compiler. **You can exclusively call `output` in component and directive property initializers.**
+
## Emitting event data
You can pass event data when calling `emit`:
@@ -52,12 +54,12 @@ When defining an event listener in a template, you can access the event data fro
## Customizing output names
-The `@Output` decorator accepts a parameter that lets you specify a different name for the event in a template:
+The `output` function accepts a parameter that lets you specify a different name for the event in a template:
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Output('valueChanged') changed = new EventEmitter();
+ changed = output({alias: 'valueChanged'});
}
@@ -69,6 +71,76 @@ This alias does not affect usage of the property in TypeScript code.
While you should generally avoid aliasing outputs for components, this feature can be useful for renaming properties while preserving an alias for the original name or for avoiding collisions with the name of native DOM events.
+## Subscribing to outputs programmatically
+
+When creating a component dynamically, you can programmatically subscribe to output events
+from the component instance. The `OutputRef` type includes a `subscribe` method:
+
+```ts
+const someComponentRef: ComponentRef = viewContainerRef.createComponent(/*...*/);
+
+someComponentRef.instance.someEventProperty.subscribe(eventData => {
+ console.log(eventData);
+});
+```
+
+Angular automatically cleans up event subscriptions when it destroys components with subscribers. Alternatively, you can manually unsubscribe from an event. The `subscribe` function returns an `OutputRefSubscription` with an `unsubscribe` method:
+
+```typescript
+const eventSubscription = someComponent.someEventProperty.subscribe(eventData => {
+ console.log(eventData);
+});
+
+// ...
+
+eventSubscription.unsubscribe();
+```
+
+## Choosing event names
+
+Avoid choosing output names that collide with events on DOM elements like HTMLElement. Name collisions introduce confusion about whether the bound property belongs to the component or the DOM element.
+
+Avoid adding prefixes for component outputs like you would with component selectors. Since a given element can only host one component, any custom properties can be assumed to belong to the component.
+
+Always use [camelCase](https://en.wikipedia.org/wiki/Camel_case) output names. Avoid prefixing output names with "on".
+
+## Using outputs with RxJS
+
+See [RxJS interop with component and directive outputs](ecosystem/rxjs-interop/output-interop) for details on interoperability between outputs and RxJS.
+
+## Declaring outputs with the `@Output` decorator
+
+Tip: While the Angular team recommends using the `output` function for new projects, the
+original decorator-based `@Output` API remains fully supported.
+
+You can alternatively define custom events by assigning a property to a new `EventEmitter` and adding the `@Output` decorator:
+
+
+@Component({/*...*/})
+export class ExpandablePanel {
+ @Output() panelClosed = new EventEmitter();
+}
+
+
+You can emit an event by calling the `emit` method on the `EventEmitter`.
+
+### Aliases with the `@Output` decorator
+
+The `@Output` decorator accepts a parameter that lets you specify a different name for the event in a template:
+
+
+@Component({/*...*/})
+export class CustomSlider {
+ @Output('valueChanged') changed = new EventEmitter();
+}
+
+
+```angular-html
+
+```
+
+This alias does not affect usage of the property in TypeScript code.
+
## Specify outputs in the `@Component` decorator
In addition to the `@Output` decorator, you can also specify a component's outputs with the `outputs` property in the `@Component` decorator. This can be useful when a component inherits a property from a base class:
@@ -76,7 +148,7 @@ In addition to the `@Output` decorator, you can also specify a component's outpu
// `CustomSlider` inherits the `valueChanged` property from `BaseSlider`.
@Component({
- ...,
+ /*...*/
outputs: ['valueChanged'],
})
export class CustomSlider extends BaseSlider {}
@@ -87,16 +159,8 @@ You can additionally specify an output alias in the `outputs` list by putting th
// `CustomSlider` inherits the `valueChanged` property from `BaseSlider`.
@Component({
- ...,
+ /*...*/
outputs: ['valueChanged: volumeChanged'],
})
export class CustomSlider extends BaseSlider {}
-
-## Choosing event names
-
-Avoid choosing output names that collide with events on DOM elements like HTMLElement. Name collisions introduce confusion about whether the bound property belongs to the component or the DOM element.
-
-Avoid adding prefixes for component outputs like you would with component selectors. Since a given element can only host one component, any custom properties can be assumed to belong to the component.
-
-Always use [camelCase](https://en.wikipedia.org/wiki/Camel_case) output names. Avoid prefixing output names with "on".
diff --git a/adev-ja/src/content/guide/components/outputs.md b/adev-ja/src/content/guide/components/outputs.md
index 325f4445c..33133af81 100644
--- a/adev-ja/src/content/guide/components/outputs.md
+++ b/adev-ja/src/content/guide/components/outputs.md
@@ -2,12 +2,12 @@
Tip: このガイドは、[基本概念のガイド](essentials) を既読していることを前提としています。Angularを初めて使用する場合は、まずそちらをお読みください。
-Angularコンポーネントは、新しい `EventEmitter` にプロパティを割り当てて `@Output` デコレーターを追加することで、カスタムイベントを定義できます。
+Angularコンポーネントは、`output`関数にプロパティを割り当てることでカスタムイベントを定義できます。
-
-@Component({...})
+
+@Component({/*...*/})
export class ExpandablePanel {
- @Output() panelClosed = new EventEmitter();
+ panelClosed = output();
}
@@ -15,36 +15,38 @@ export class ExpandablePanel {
```
-`EventEmitter` の `emit` メソッドを呼び出すことで、イベントを送信できます。
+`output`関数は`OutputEmitterRef`を返します。`OutputEmitterRef`の`emit`メソッドを呼び出すことで、イベントを発生させることができます。
this.panelClosed.emit();
-Angularは、`@Output` デコレーターでマークされたプロパティを**出力**と呼びます。出力を使用して、`click` のようなネイティブブラウザイベントと同様に、他のコンポーネントにデータを渡すことができます。
+Angularでは、`output`関数で初期化されたプロパティを**出力**と呼びます。出力を使用すると、`click`などのネイティブブラウザイベントと同様に、カスタムイベントを発生させることができます。
**Angular カスタムイベントは DOM を伝播しません。**
**出力名は、大文字と小文字が区別されます。**
-コンポーネントクラスを拡張する場合、**出力は子クラスによって継承されます。**
+コンポーネントクラスを拡張する場合、**outputsは子クラスによって継承されます。**
-## イベントデータの送信
+`output`関数は、Angularコンパイラにとって特別な意味を持ちます。**`output`は、コンポーネントとディレクティブのプロパティ初期化子でのみ呼び出すことができます。**
-`emit` を呼び出す際にイベントデータを渡すことができます。
+## イベントデータの送出
+
+`emit`を呼び出す際に、イベントデータを渡すことができます。
-// プリミティブ値を送信できます。
+// プリミティブ値を送出できます。
this.valueChanged.emit(7);
-// カスタムイベントオブジェクトを送信できます
+// カスタムイベントオブジェクトを送出できます
this.thumbDropped.emit({
pointerX: 123,
pointerY: 456,
})
-テンプレートでイベントリスナーを定義する場合、`$event` 変数からイベントデータにアクセスできます。
+テンプレートでイベントリスナーを定義する場合、`$event`変数からイベントデータにアクセスできます。
```angular-html
@@ -52,12 +54,12 @@ this.thumbDropped.emit({
## 出力名のカスタマイズ
-`@Output` デコレーターは、テンプレートでイベントに異なる名前を指定できるパラメータを受け取ります。
+`output`関数は、テンプレートでイベントに異なる名前を指定できるパラメーターを受け入れます。
-@Component({...})
+@Component({/*...*/})
export class CustomSlider {
- @Output('valueChanged') changed = new EventEmitter();
+ changed = output({alias: 'valueChanged'});
}
@@ -67,36 +69,98 @@ export class CustomSlider {
このエイリアスは、TypeScriptコードでのプロパティの使用には影響しません。
-コンポーネントの出力のエイリアスは一般的に避けるべきですが、この機能は、元の名前のエイリアスを保持しながらプロパティの名前を変更したり、ネイティブDOMイベントの名前との衝突を回避したりするのに役立ちます。
+一般的に、コンポーネントの出力のエイリアスは避けるべきですが、この機能は元の名前のエイリアスを保持しながらプロパティの名前を変更する場合や、ネイティブDOMイベントの名前との衝突を避ける場合に役立ちます。
+
+## プログラムによる出力の購読
+
+コンポーネントを動的に作成する場合は、コンポーネントインスタンスから出力イベントをプログラムで購読できます。
+`OutputRef`型には`subscribe`メソッドが含まれています。
+
+```ts
+const someComponentRef: ComponentRef = viewContainerRef.createComponent(/*...*/);
+
+someComponentRef.instance.someEventProperty.subscribe(eventData => {
+ console.log(eventData);
+});
+```
+
+Angularは、サブスクライバーを持つコンポーネントを破棄するときに、イベントサブスクリプションを自動的にクリーンアップします。または、イベントから手動で購読解除できます。`subscribe`関数は、`unsubscribe`メソッドを持つ`OutputRefSubscription`を返します。
+
+```typescript
+const eventSubscription = someComponent.someEventProperty.subscribe(eventData => {
+ console.log(eventData);
+});
+
+// ...
+
+eventSubscription.unsubscribe();
+```
+
+## イベント名の選択
+
+HTMLElementなどのDOM要素のイベントと衝突する出力名を選択することは避けてください。名前の衝突は、バインドされたプロパティがコンポーネントのものであるか、DOM要素のものであるかについて混乱を招きます。
+
+コンポーネントセレクターのように、コンポーネント出力にプレフィックスを追加することは避けてください。特定の要素は1つのコンポーネントしかホストできないため、カスタムプロパティはすべてコンポーネントに属すると見なすことができます。
+
+常に[camelCase](https://en.wikipedia.org/wiki/Camel_case)出力名を使用してください。「on」で始まる出力名は避けてください。
+
+## RxJSを使用したoutputs
+
+outputsとRxJSの相互運用性については、[RxJS interop with component and directive outputs](ecosystem/rxjs-interop/output-interop)を参照してください。
+
+## `@Output`デコレーターを使用した出力の宣言
+
+Tip: Angularチームは新規プロジェクトでは`output`関数の使用を推奨していますが、
+元のデコレーターベースの`@Output`APIは引き続き完全にサポートされています。
+
+代替として、新しい`EventEmitter`にプロパティを割り当て、`@Output`デコレーターを追加することで、カスタムイベントを定義できます。
+
+
+@Component({/*...*/})
+export class ExpandablePanel {
+ @Output() panelClosed = new EventEmitter();
+}
+
+
+`EventEmitter`の`emit`メソッドを呼び出すことで、イベントを発生させることができます。
-## `@Component` デコレーターで出力名を指定する
+### `@Output`デコレーターを使用したエイリアス
-`@Output` デコレーターに加えて、`@Component` デコレーターの `outputs` プロパティを使用して、コンポーネントの出力名を指定できます。これは、コンポーネントが基本クラスからプロパティを継承する場合に役立ちます。
+`@Output`デコレーターは、テンプレートでイベントに異なる名前を指定できるパラメーターを受け入れます。
-// `CustomSlider` は、`BaseSlider` から `valueChanged` プロパティを継承します。
+@Component({/*...*/})
+export class CustomSlider {
+ @Output('valueChanged') changed = new EventEmitter();
+}
+
+
+```angular-html
+
+```
+
+このエイリアスは、TypeScriptコードでのプロパティの使用には影響しません。
+
+## `@Component`デコレーターでの出力の指定
+
+`@Output`デコレーターに加えて、`@Component`デコレーターの`outputs`プロパティを使用して、コンポーネントの出力を指定できます。これは、コンポーネントが基底クラスからプロパティを継承する場合に役立ちます。
+
+
+// `CustomSlider`は`BaseSlider`から`valueChanged`プロパティを継承します。
@Component({
- ...,
+ /*...*/
outputs: ['valueChanged'],
})
export class CustomSlider extends BaseSlider {}
-さらに、`outputs` リストでコロンの後にエイリアスを置くことで、出力のエイリアスを指定できます。
+`outputs`リストにエイリアスも指定できます。エイリアスは文字列の後にコロンを付けて記述します。
-// `CustomSlider` は、`BaseSlider` から `valueChanged` プロパティを継承します。
+// `CustomSlider`は`BaseSlider`から`valueChanged`プロパティを継承します。
@Component({
- ...,
+ /*...*/
outputs: ['valueChanged: volumeChanged'],
})
export class CustomSlider extends BaseSlider {}
-
-## イベント名の選択
-
-`HTMLElement` などのDOM要素のイベントと衝突する出力名を選ぶことは避けてください。名前が衝突すると、バインドされているプロパティがコンポーネントに属しているのか、DOM要素に属しているのかがわかりにくくなります。
-
-コンポーネントセレクターのように、コンポーネント出力にプレフィックスを追加することは避けてください。特定の要素には、1つのコンポーネントしかホストできないため、カスタムプロパティはすべてコンポーネントに属していると見なすことができます。
-
-出力名には常に[キャメルケース](https://en.wikipedia.org/wiki/Camel_case)を使用してください。出力名の前に「on」を付けることは避けてください。
diff --git a/adev-ja/src/content/guide/components/queries.en.md b/adev-ja/src/content/guide/components/queries.en.md
index 3374d40df..b1df7f992 100644
--- a/adev-ja/src/content/guide/components/queries.en.md
+++ b/adev-ja/src/content/guide/components/queries.en.md
@@ -6,16 +6,19 @@ A component can define **queries** that find child elements and read values from
Developers most commonly use queries to retrieve references to child components, directives, DOM elements, and more.
+All query functions return signals that reflect the most up-to-date results. You can read the
+result by calling the signal function, including in reactive contexts like `computed` and `effect`.
+
There are two categories of query: **view queries** and **content queries.**
## View queries
-View queries retrieve results from the elements in the component's _view_ — the elements defined in the component's own template. You can query for a single result with the `@ViewChild` decorator.
+View queries retrieve results from the elements in the component's _view_ — the elements defined in the component's own template. You can query for a single result with the `viewChild` function.
-
+
@Component({
selector: 'custom-card-header',
- ...
+ /*...*/
})
export class CustomCardHeader {
text: string;
@@ -26,26 +29,21 @@ export class CustomCardHeader {
template: 'Visit sunny California!',
})
export class CustomCard {
- @ViewChild(CustomCardHeader) header: CustomCardHeader;
-
- ngAfterViewInit() {
- console.log(this.header.text);
- }
+ header = viewChild(CustomCardHeader);
+ headerText = computed(() => this.header()?.text);
}
-In this example, the `CustomCard` component queries for a child `CustomCardHeader` and accesses the result in `ngAfterViewInit`.
+In this example, the `CustomCard` component queries for a child `CustomCardHeader` and uses the result in a `computed`.
-If the query does not find a result, its value is `undefined`. This may occur if the target element is hidden by `NgIf`. Angular keeps the result of `@ViewChild` up to date as your application state changes.
+If the query does not find a result, its value is `undefined`. This may occur if the target element is hidden by `@if`. Angular keeps the result of `viewChild` up to date as your application state changes.
-**View query results become available in the `ngAfterViewInit` lifecycle method**. Before this point, the value is `undefined`. See the [Lifecycle](guide/components/lifecycle) section for details on the component lifecycle.
-
-You can also query for multiple results with the `@ViewChildren` decorator.
+You can also query for multiple results with the `viewChildren` function.
@Component({
selector: 'custom-card-action',
- ...,
+ /*...*/
})
export class CustomCardAction {
text: string;
@@ -59,28 +57,23 @@ export class CustomCardAction {
`,
})
export class CustomCard {
- @ViewChildren(CustomCardAction) actions: QueryList;
-
- ngAfterViewInit() {
- this.actions.forEach(action => {
- console.log(action.text);
- });
- }
+ actions = viewChildren(CustomCardAction);
+ actionsTexts = computed(() => this.actions().map(action => action.text);
}
-`@ViewChildren` creates a `QueryList` object that contains the query results. You can subscribe to changes to the query results over time via the `changes` property.
+`viewChildren` creates a signal with an `Array` of the query results.
**Queries never pierce through component boundaries.** View queries can only retrieve results from the component's template.
## Content queries
-Content queries retrieve results from the elements in the component's _content_— the elements nested inside the component in the template where it's used. You can query for a single result with the `@ContentChild` decorator.
+Content queries retrieve results from the elements in the component's _content_— the elements nested inside the component in the template where it's used. You can query for a single result with the `contentChild` function.
-
+
@Component({
selector: 'custom-toggle',
- ...
+ /*...*/
})
export class CustomToggle {
text: string;
@@ -88,18 +81,16 @@ export class CustomToggle {
@Component({
selector: 'custom-expando',
- ...
+ /*...*/
})
export class CustomExpando {
- @ContentChild(CustomToggle) toggle: CustomToggle;
-
- ngAfterContentInit() {
- console.log(this.toggle.text);
- }
+ toggle = contentChild(CustomToggle);
+ toggleText = computed(() => this.toggle()?.text);
}
-@Component({
- selector: 'user-profile',
+@Component({
+ /* ... */
+ // CustomToggle is used inside CustomExpando as content.
template: `
Show
@@ -109,20 +100,18 @@ export class CustomExpando {
export class UserProfile { }
-In this example, the `CustomExpando` component queries for a child `CustomToggle` and accesses the result in `ngAfterContentInit`.
+In this example, the `CustomExpando` component queries for a child `CustomToggle` and accesses the result in a `computed`.
-If the query does not find a result, its value is `undefined`. This may occur if the target element is absent or hidden by `NgIf`. Angular keeps the result of `@ContentChild` up to date as your application state changes.
+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.
By default, content queries find only _direct_ children of the component and do not traverse into descendants.
-**Content query results become available in the `ngAfterContentInit` lifecycle method**. Before this point, the value is `undefined`. See the [Lifecycle](guide/components/lifecycle) section for details on the component lifecycle.
-
-You can also query for multiple results with the `@ContentChildren` decorator.
+You can also query for multiple results with the `contentChildren` function.
@Component({
selector: 'custom-menu-item',
- ...
+ /*...*/
})
export class CustomMenuItem {
text: string;
@@ -130,16 +119,11 @@ export class CustomMenuItem {
@Component({
selector: 'custom-menu',
- ...,
+ /*...*/
})
export class CustomMenu {
- @ContentChildren(CustomMenuItem) items: QueryList;
-
- ngAfterContentInit() {
- this.items.forEach(item => {
- console.log(item.text);
- });
- }
+ items = contentChildren(CustomMenuItem);
+ itemTexts = computed(() => this.items().map(item => item.text));
}
@Component({
@@ -154,10 +138,26 @@ export class CustomMenu {
export class UserProfile { }
-`@ContentChildren` creates a `QueryList` object that contains the query results. You can subscribe to changes to the query results over time via the `changes` property.
+`contentChildren` creates a signal with an `Array` of the query results.
**Queries never pierce through component boundaries.** Content queries can only retrieve results from the same template as the component itself.
+## Required queries
+
+If a child query (`viewChild` or `contentChild`) does not find a result, its value is `undefined`. This may occur if the target element is hidden by a control flow statement like `@if` or `@for`. Because of this, the child queries return a signal that include `undefined` in their value type.
+
+If some cases, especially with `viewChild`, you know with certainty that a specific child is always available. In other cases, you may want to strictly enforce that a specific child is present. For these cases, you can use a *required query*.
+
+```angular-ts
+@Component({/* ... */})
+export class CustomCard {
+ header = viewChild.required(CustomCardHeader);
+ body = contentChild.required(CustomCardBody);
+}
+```
+
+If a required query does not find a matching result, Angular reports an error. Because this guarantees that a result is available, require queries do not automatially include `undefined` in the signal's value type.
+
## Query locators
This first parameter for each query decorator is its **locator**.
@@ -169,14 +169,14 @@ a [template reference variable](guide/templates/variables#template-reference-var
```angular-ts
@Component({
- ...,
+ /*...*/
template: `
`
})
export class ActionBar {
- @ViewChild('save') saveButton: ElementRef;
+ saveButton = viewChild>('save');
}
```
@@ -194,14 +194,14 @@ For more advanced cases, you can use any `ProviderToken` as a locator. This lets
const SUB_ITEM = new InjectionToken('sub-item');
@Component({
- ...,
+ /*...*/
providers: [{provide: SUB_ITEM, useValue: 'special-item'}],
})
export class SpecialItem { }
-@Component({...})
+@Component({/*...*/})
export class CustomList {
- @ContentChild(SUB_ITEM) subItemType: string;
+ subItemType = contentChild(SUB_ITEM);
}
```
@@ -209,31 +209,23 @@ The above example uses an `InjectionToken` as a locator, but you can use any `Pr
## Query options
-All query decorators accept an options object as a second parameter. These options control how the query finds its results.
+All query functions accept an options object as a second parameter. These options control how the query finds its results.
-### Static queries
-
-`@ViewChild` and `@ContentChild` queries accept the `static` option.
+### Reading specific values from an element's injector
-```angular-ts
-@Component({
- selector: 'custom-card',
- template: 'Visit sunny California!',
-})
-export class CustomCard {
- @ViewChild(CustomCardHeader, {static: true}) header: CustomCardHeader;
+By default, the query locator indicates both the element you're searching for and the value retrieved. You can alternatively specify the `read` option to retrieve a different value from the element matched by the locator.
- ngOnInit() {
- console.log(this.header.text);
- }
+```ts
+@Component({/*...*/})
+export class CustomExpando {
+ toggle = contentChild(ExpandoContent, {read: TemplateRef});
}
```
-By setting `static: true`, you guarantee to Angular that the target of this query is _always_ present and is not conditionally rendered. This makes the result available earlier, in the `ngOnInit` lifecycle method.
-
-Static query results do not update after initialization.
+The above example, locates an element with the directive `ExpandoContent` and retrieves
+the `TemplateRef` associated with that element.
-The `static` option is not available for `@ViewChildren` and `@ContentChildren` queries.
+Developers most commonly use `read` to retrieve `ElementRef` and `TemplateRef`.
### Content descendants
@@ -242,10 +234,10 @@ By default, content queries find only _direct_ children of the component and do
@Component({
selector: 'custom-expando',
- ...
+ /*...*/
})
export class CustomExpando {
- @ContentChild(CustomToggle) toggle: CustomToggle;
+ toggle = contentChild(CustomToggle);
}
@Component({
@@ -266,23 +258,185 @@ In the example above, `CustomExpando` cannot find `` because it i
View queries do not have this option because they _always_ traverse into descendants.
-### Reading specific values from an element's injector
+## Decorator-based queries
+Tip: While the Angular team recommends using the signal-based query function for new projects, the
+original decorator-based query APIs remain fully supported.
-By default, the query locator indicates both the element you're searching for and the value retrieved. You can alternatively specify the `read` option to retrieve a different value from the element matched by the locator.
+You can alternatively declare queries by adding the corresponding decorator to a property. Decorator-based queries behave the same way as signal-based queries except as described below.
-```ts
-@Component({...})
+### View queries
+
+You can query for a single result with the `@ViewChild` decorator.
+
+
+@Component({
+ selector: 'custom-card-header',
+ /*...*/
+})
+export class CustomCardHeader {
+ text: string;
+}
+
+@Component({
+ selector: 'custom-card',
+ template: 'Visit sunny California!',
+})
+export class CustomCard {
+ @ViewChild(CustomCardHeader) header: CustomCardHeader;
+
+ ngAfterViewInit() {
+ console.log(this.header.text);
+ }
+}
+
+
+In this example, the `CustomCard` component queries for a child `CustomCardHeader` and accesses the result in `ngAfterViewInit`.
+
+Angular keeps the result of `@ViewChild` up to date as your application state changes.
+
+**View query results become available in the `ngAfterViewInit` lifecycle method**. Before this point, the value is `undefined`. See the [Lifecycle](guide/components/lifecycle) section for details on the component lifecycle.
+
+You can also query for multiple results with the `@ViewChildren` decorator.
+
+
+@Component({
+ selector: 'custom-card-action',
+ /*...*/
+})
+export class CustomCardAction {
+ text: string;
+}
+
+@Component({
+ selector: 'custom-card',
+ template: `
+ Save
+ Cancel
+ `,
+})
+export class CustomCard {
+ @ViewChildren(CustomCardAction) actions: QueryList;
+
+ ngAfterViewInit() {
+ this.actions.forEach(action => {
+ console.log(action.text);
+ });
+ }
+}
+
+
+`@ViewChildren` creates a `QueryList` object that contains the query results. You can subscribe to changes to the query results over time via the `changes` property.
+
+### Content queries
+
+You can query for a single result with the `@ContentChild` decorator.
+
+
+@Component({
+ selector: 'custom-toggle',
+ /*...*/
+})
+export class CustomToggle {
+ text: string;
+}
+
+@Component({
+ selector: 'custom-expando',
+ /*...*/
+})
export class CustomExpando {
- @ContentChild(ExpandoContent, {read: TemplateRef}) toggle: TemplateRef;
+ @ContentChild(CustomToggle) toggle: CustomToggle;
+
+ ngAfterContentInit() {
+ console.log(this.toggle.text);
+ }
+}
+
+@Component({
+ selector: 'user-profile',
+ template: `
+
+ Show
+
+ `
+})
+export class UserProfile { }
+
+
+In this example, the `CustomExpando` component queries for a child `CustomToggle` and accesses the result in `ngAfterContentInit`.
+
+Angular keeps the result of `@ContentChild` up to date as your application state changes.
+
+**Content query results become available in the `ngAfterContentInit` lifecycle method**. Before this point, the value is `undefined`. See the [Lifecycle](guide/components/lifecycle) section for details on the component lifecycle.
+
+You can also query for multiple results with the `@ContentChildren` decorator.
+
+
+@Component({
+ selector: 'custom-menu-item',
+ /*...*/
+})
+export class CustomMenuItem {
+ text: string;
+}
+
+@Component({
+ selector: 'custom-menu',
+ /*...*/
+})
+export class CustomMenu {
+ @ContentChildren(CustomMenuItem) items: QueryList;
+
+ ngAfterContentInit() {
+ this.items.forEach(item => {
+ console.log(item.text);
+ });
+ }
+}
+
+@Component({
+ selector: 'user-profile',
+ template: `
+
+ Cheese
+ Tomato
+
+ `
+})
+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.
+
+### Decorator-based query options
+
+All query decorators accept an options object as a second parameter. These options work the same way as signal-based queries except where described below.
+
+### Static queries
+
+`@ViewChild` and `@ContentChild` decorators accept the `static` option.
+
+```angular-ts
+@Component({
+ selector: 'custom-card',
+ template: 'Visit sunny California!',
+})
+export class CustomCard {
+ @ViewChild(CustomCardHeader, {static: true}) header: CustomCardHeader;
+
+ ngOnInit() {
+ console.log(this.header.text);
+ }
}
```
-The above example, locates an element with the directive `ExpandoContent` and retrieves
-the `TemplateRef` associated with that element.
+By setting `static: true`, you guarantee to Angular that the target of this query is _always_ present and is not conditionally rendered. This makes the result available earlier, in the `ngOnInit` lifecycle method.
-Developers most commonly use `read` to retrieve `ElementRef` and `TemplateRef`.
+Static query results do not update after initialization.
+
+The `static` option is not available for `@ViewChildren` and `@ContentChildren` queries.
-## Using QueryList
+### Using QueryList
`@ViewChildren` and `@ContentChildren` both provide a `QueryList` object that contains a list of results.
diff --git a/adev-ja/src/content/guide/components/queries.md b/adev-ja/src/content/guide/components/queries.md
index 1bae801bc..5a8a4e072 100644
--- a/adev-ja/src/content/guide/components/queries.md
+++ b/adev-ja/src/content/guide/components/queries.md
@@ -6,16 +6,19 @@ Tip: このガイドでは、[基本概念のガイド](essentials)を読んで
開発者は、クエリを使用して、子コンポーネント、ディレクティブ、DOM要素などの参照を取得することがほとんどです。
-クエリには、**ビュークエリ**と**コンテンツクエリ**の2種類があります。
+すべてのクエリ関数は、最新の結果を反映するシグナルを返します。
+`computed`や`effect`などのリアクティブなコンテキストでも、シグナル関数を呼び出すことで結果を読み取れます。
+
+クエリには、**ビュークエリ**と**コンテンツクエリ**の2つのカテゴリーがあります。
## ビュークエリ
-ビュークエリは、コンポーネントの*ビュー*(コンポーネント自身のテンプレートで定義されている要素)にある要素から結果を取得します。`@ViewChild` デコレーターを使用して、単一の結果をクエリできます。
+ビュークエリは、コンポーネントの_ビュー_(コンポーネント自身のテンプレートで定義された要素)内の要素から結果を取得します。`viewChild`関数を使用して単一の結果をクエリできます。
-
+
@Component({
selector: 'custom-card-header',
- ...
+ /*...*/
})
export class CustomCardHeader {
text: string;
@@ -26,26 +29,21 @@ export class CustomCardHeader {
template: 'Visit sunny California!',
})
export class CustomCard {
- @ViewChild(CustomCardHeader) header: CustomCardHeader;
-
- ngAfterViewInit() {
- console.log(this.header.text);
- }
+ header = viewChild(CustomCardHeader);
+ headerText = computed(() => this.header()?.text);
}
-この例では、`CustomCard`コンポーネントは子要素の`CustomCardHeader`をクエリし、`ngAfterViewInit`で結果にアクセスしています。
+この例では、`CustomCard`コンポーネントは子`CustomCardHeader`をクエリし、`computed`で結果を使用しています。
-クエリが結果を見つけられない場合、その値は`undefined`になります。これは、ターゲット要素が`NgIf`によって非表示になっている場合に発生する可能性があります。Angularは、アプリケーションの状態が変化すると、`@ViewChild`の結果を最新の状態に保ちます。
+クエリが結果を見つけられない場合、その値は`undefined`になります。これは、ターゲット要素が`@if`によって非表示になっている場合に発生する可能性があります。Angularは、アプリケーションの状態が変化するにつれて`viewChild`の結果を最新の状態に保ちます。
-**ビュークエリの結果は、`ngAfterViewInit`ライフサイクルメソッドで利用可能になります**。この時点以前は、値は`undefined`です。コンポーネントライフサイクルの詳細については、[ライフサイクル](guide/components/lifecycle)セクションをご覧ください。
-
-`@ViewChildren` デコレーターを使用して、複数の結果をクエリできます。
+`viewChildren`関数を使用して、複数結果をクエリできます。
@Component({
selector: 'custom-card-action',
- ...,
+ /*...*/
})
export class CustomCardAction {
text: string;
@@ -59,28 +57,23 @@ export class CustomCardAction {
`,
})
export class CustomCard {
- @ViewChildren(CustomCardAction) actions: QueryList;
-
- ngAfterViewInit() {
- this.actions.forEach(action => {
- console.log(action.text);
- });
- }
+ actions = viewChildren(CustomCardAction);
+ actionsTexts = computed(() => this.actions().map(action => action.text);
}
-`@ViewChildren`は、クエリの結果を含む`QueryList`オブジェクトを作成します。`changes`プロパティを使用して、クエリの結果が時間とともに変化した場合に購読できます。
+`viewChildren`は、クエリ結果の`Array`を含むシグナルを作成します。
-**クエリはコンポーネントの境界を越えることは決してありません。** ビュークエリは、コンポーネントのテンプレートからのみ結果を取得できます。
+**クエリはコンポーネントの境界を貫通することはありません。**ビュークエリは、コンポーネントのテンプレートからの結果のみを取得できます。
## コンテンツクエリ
-コンテンツクエリは、コンポーネントの_コンテンツ_(コンポーネントが使用されているテンプレート内でコンポーネントにネストされた要素)にある要素から結果を取得します。`@ContentChild` デコレーターを使用して、単一の結果をクエリできます。
+コンテンツクエリは、コンポーネントの_コンテンツ_(コンポーネントが使用されているテンプレート内でコンポーネントの中にネストされた要素)内の要素から結果を取得します。`contentChild`関数を使用して単一の結果をクエリできます。
-
+
@Component({
selector: 'custom-toggle',
- ...
+ /*...*/
})
export class CustomToggle {
text: string;
@@ -88,18 +81,16 @@ export class CustomToggle {
@Component({
selector: 'custom-expando',
- ...
+ /*...*/
})
export class CustomExpando {
- @ContentChild(CustomToggle) toggle: CustomToggle;
-
- ngAfterContentInit() {
- console.log(this.toggle.text);
- }
+ toggle = contentChild(CustomToggle);
+ toggleText = computed(() => this.toggle()?.text);
}
-@Component({
- selector: 'user-profile',
+@Component({
+ /* ... */
+ // CustomToggle is used inside CustomExpando as content.
template: `
Show
@@ -109,20 +100,18 @@ export class CustomExpando {
export class UserProfile { }
-この例では、`CustomExpando`コンポーネントは子要素の`CustomToggle`をクエリし、`ngAfterContentInit`で結果にアクセスしています。
-
-クエリが結果を見つけられない場合、その値は`undefined`になります。これは、ターゲット要素が存在しないか、`NgIf`によって非表示になっている場合に発生する可能性があります。Angularは、アプリケーションの状態が変化すると、`@ContentChild`の結果を最新の状態に保ちます。
+この例では、`CustomExpando`コンポーネントは子`CustomToggle`をクエリし、`computed`で結果にアクセスしています。
-デフォルトでは、コンテンツクエリはコンポーネントの*直接*の子要素のみを見つけ、子孫にトラバースすることはありません。
+クエリが結果を見つけられない場合、その値は`undefined`になります。これは、ターゲット要素が存在しないか、`@if`によって非表示になっている場合に発生する可能性があります。Angularは、アプリケーションの状態が変化するにつれて`contentChild`の結果を最新の状態に保ちます。
-**コンテンツクエリの結果は、`ngAfterContentInit`ライフサイクルメソッドで利用可能になります**。この時点以前は、値は`undefined`です。コンポーネントライフサイクルの詳細については、[ライフサイクル](guide/components/lifecycle)セクションをご覧ください。
+デフォルトでは、コンテンツクエリはコンポーネントの_直接_の子のみを見つけ、子孫にはトラバースしません。
-`@ContentChildren` デコレーターを使用して、複数の結果をクエリできます。
+`contentChildren`関数を使用して、複数結果をクエリできます。
@Component({
selector: 'custom-menu-item',
- ...
+ /*...*/
})
export class CustomMenuItem {
text: string;
@@ -130,16 +119,11 @@ export class CustomMenuItem {
@Component({
selector: 'custom-menu',
- ...,
+ /*...*/
})
export class CustomMenu {
- @ContentChildren(CustomMenuItem) items: QueryList;
-
- ngAfterContentInit() {
- this.items.forEach(item => {
- console.log(item.text);
- });
- }
+ items = contentChildren(CustomMenuItem);
+ itemTexts = computed(() => this.items().map(item => item.text));
}
@Component({
@@ -154,148 +138,319 @@ export class CustomMenu {
export class UserProfile { }
-`@ContentChildren`は、クエリの結果を含む`QueryList`オブジェクトを作成します。`changes`プロパティを使用して、クエリの結果が時間とともに変化した場合に購読できます。
+`contentChildren`は、クエリ結果の`Array`を含むシグナルを作成します。
+
+**クエリはコンポーネントの境界を貫通することはありません。**コンテンツクエリは、コンポーネント自体と同じテンプレートからの結果のみを取得できます。
-**クエリはコンポーネントの境界を越えることは決してありません。** コンテンツクエリは、コンポーネント自身と同じテンプレートからのみ結果を取得できます。
+## 必須クエリ
+
+子クエリ(`viewChild`または`contentChild`)が結果を見つけられない場合、その値は`undefined`になります。これは、ターゲット要素が`@if`や`@for`などの制御フロー文によって非表示になっている場合に発生する可能性があります。このため、子クエリは`undefined`を含む値型を持つシグナルを返します。
+
+場合によっては、特に`viewChild`を使用する場合、特定の子が常に利用可能であることが確実な場合があります。他の場合では、特定の子が存在することを厳格に適用したい場合があります。これらの場合、*必須クエリ*を使用できます。
+
+```angular-ts
+@Component({/* ... */})
+export class CustomCard {
+ header = viewChild.required(CustomCardHeader);
+ body = contentChild.required(CustomCardBody);
+}
+```
+
+必須クエリが一致する結果を見つけられない場合、Angularはエラーを報告します。これは結果が利用可能であることを保証するため、必須クエリは自動的にシグナルの値型に`undefined`を含めません。
## クエリロケーター
-各クエリのデコレーターの最初の引数は、**ロケーター**です。
+各クエリデコレーターの最初の引数は、その**ロケーター**です。
-ほとんどの場合、コンポーネントまたはディレクティブをロケーターとして使用します。
+ほとんどの場合、ロケーターとしてコンポーネントまたはディレクティブを使用することをお勧めします。
-代わりに、[テンプレート参照変数](guide/templates/variables#template-reference-variables)
-に対応する文字列ロケーターを指定できます。
+[テンプレート参照変数](guide/templates/variables#template-reference-variables)に対応する
+文字列ロケーターも指定できます。
```angular-ts
@Component({
- ...,
+ /*...*/
template: `
`
})
export class ActionBar {
- @ViewChild('save') saveButton: ElementRef;
+ saveButton = viewChild>('save');
}
```
-同じテンプレート参照変数を定義している要素が複数ある場合、クエリは最初に一致する要素を取得します。
+複数の要素が同じテンプレート参照変数を定義している場合、クエリは最初に一致する要素を取得します。
-Angularは、CSSセレクターをクエリのロケーターとしてサポートしていません。
+Angularは、CSSセレクターをクエリロケーターとしてサポートしていません。
### クエリとインジェクターツリー
-Tip: プロバイダーとAngularのインジェクションツリーの詳細については、[依存性注入](guide/di)を参照してください。
+Tip: プロバイダーとAngularのインジェクションツリーについては、[依存性の注入](guide/di)を参照してください。
-より高度なケースでは、`ProviderToken`をロケーターとして使用できます。これにより、コンポーネントとディレクティブのプロバイダーに基づいて要素を特定できます。
+より高度なケースでは、ロケーターとして任意の`ProviderToken`を使用できます。これにより、コンポーネントとディレクティブのプロバイダーに基づいて要素を見つけることができます。
```angular-ts
const SUB_ITEM = new InjectionToken('sub-item');
@Component({
- ...,
+ /*...*/
providers: [{provide: SUB_ITEM, useValue: 'special-item'}],
})
export class SpecialItem { }
-@Component({...})
+@Component({/*...*/})
export class CustomList {
- @ContentChild(SUB_ITEM) subItemType: string;
+ subItemType = contentChild(SUB_ITEM);
}
```
-上記の例では、`InjectionToken`をロケーターとして使用していますが、特定の要素を特定するために、任意の`ProviderToken`を使用できます。
+上記の例では、ロケーターとして`InjectionToken`を使用していますが、任意の`ProviderToken`を使用して特定の要素を見つけることができます。
## クエリオプション
-すべてのクエリデコレーターは、2番目のパラメーターとしてオプションオブジェクトを受け取ります。これらのオプションは、クエリが結果をどのように見つけるかを制御します。
+すべてのクエリ関数は、第2引数としてオプションオブジェクトを受け取ります。これらのオプションは、クエリが結果を見つける方法を制御します。
-### 静的クエリ
+### 要素のインジェクターからの特定の値の読み取り
-`@ViewChild`および`@ContentChild`クエリは、`static`オプションを受け取ります。
+デフォルトでは、クエリロケーターは、検索対象の要素と取得される値の両方を示します。代わりに、`read`オプションを指定して、ロケーターによって一致した要素から別の値を取得できます。
+
+```ts
+@Component({/*...*/})
+export class CustomExpando {
+ toggle = contentChild(ExpandoContent, {read: TemplateRef});
+}
+```
+
+上記の例では、`ExpandoContent`ディレクティブを持つ要素を見つけて、
+その要素に関連付けられた`TemplateRef`を取得します。
+
+開発者は、`read`を使用して`ElementRef`と`TemplateRef`を取得することが最も一般的です。
+
+### コンテンツの子孫
+
+デフォルトでは、コンテンツクエリはコンポーネントの_直接_の子のみを見つけ、子孫にはトラバースしません。
+
+
+@Component({
+ selector: 'custom-expando',
+ /*...*/
+})
+export class CustomExpando {
+ toggle = contentChild(CustomToggle);
+}
+
+@Component({
+ selector: 'user-profile',
+ template: `
+
+
+
+ Show
+
+
+ `
+})
+export class UserProfile { }
+
+
+上記の例では、`CustomExpando`は``を見つけられません。これは、``の直接の子ではないためです。`descendants: true`を設定することで、同じテンプレート内のすべての子孫をトラバースするようにクエリを構成できます。ただし、クエリは他のテンプレートの要素をトラバースするためにコンポーネントを_決して_貫通することはありません。
+
+ビュークエリにはこのオプションはありません。これは、常に子孫をトラバースするためです。
+
+## デコレーターベースのクエリ
+Tip: Angularチームは新規プロジェクトにはシグナルベースのクエリ関数の使用を推奨していますが、
+元のデコレーターベースのクエリAPIは引き続き完全にサポートされています。
+
+代わりに、対応するデコレーターをプロパティに追加することでもクエリを宣言できます。デコレーターベースのクエリは、下記で説明する点を除いて、シグナルベースのクエリと同じように動作します。
+
+### ビュークエリ
+
+`@ViewChild`デコレーターを使用して、単一の結果をクエリできます。
+
+
+@Component({
+ selector: 'custom-card-header',
+ /*...*/
+})
+export class CustomCardHeader {
+ text: string;
+}
-```angular-ts
@Component({
selector: 'custom-card',
template: 'Visit sunny California!',
})
export class CustomCard {
- @ViewChild(CustomCardHeader, {static: true}) header: CustomCardHeader;
+ @ViewChild(CustomCardHeader) header: CustomCardHeader;
- ngOnInit() {
+ ngAfterViewInit() {
console.log(this.header.text);
}
}
-```
+
-`static: true`を設定することで、Angularにこのクエリのターゲットが*常に*存在し、条件付きでレンダリングされていないことを保証します。これにより、結果はより早い段階で、`ngOnInit`ライフサイクルメソッドで利用可能になります。
+この例では、`CustomCard`コンポーネントは子`CustomCardHeader`をクエリし、`ngAfterViewInit`で結果にアクセスしています。
-静的クエリの結果は、初期化後に更新されません。
+Angularは、アプリケーションの状態が変化するにつれて`@ViewChild`の結果を最新の状態に保ちます。
+
+**ビュークエリの結果は`ngAfterViewInit`ライフサイクルメソッドで使用可能になります。**この時点より前では、値は`undefined`です。コンポーネントライフサイクルの詳細については、[ライフサイクル](guide/components/lifecycle)セクションを参照してください。
+
+`@ViewChildren`デコレーターを使用して、複数の結果をクエリできます。
+
+
+@Component({
+ selector: 'custom-card-action',
+ /*...*/
+})
+export class CustomCardAction {
+ text: string;
+}
-`static`オプションは、`@ViewChildren`および`@ContentChildren`クエリでは使用できません。
+@Component({
+ selector: 'custom-card',
+ template: `
+ Save
+ Cancel
+ `,
+})
+export class CustomCard {
+ @ViewChildren(CustomCardAction) actions: QueryList;
+
+ ngAfterViewInit() {
+ this.actions.forEach(action => {
+ console.log(action.text);
+ });
+ }
+}
+
-### コンテンツ子孫
+`@ViewChildren`は、クエリ結果を含む`QueryList`オブジェクトを作成します。`changes`プロパティを使用して、時間の経過とともにクエリ結果の変更を購読できます。
-デフォルトでは、コンテンツクエリはコンポーネントの_直接_の子要素のみを見つけ、子孫にトラバースすることはありません。
+### コンテンツクエリ
+
+`@ContentChild`デコレーターを使用して、単一の結果をクエリできます。
+
+
+@Component({
+ selector: 'custom-toggle',
+ /*...*/
+})
+export class CustomToggle {
+ text: string;
+}
-
@Component({
selector: 'custom-expando',
- ...
+ /*...*/
})
export class CustomExpando {
@ContentChild(CustomToggle) toggle: CustomToggle;
+
+ ngAfterContentInit() {
+ console.log(this.toggle.text);
+ }
}
@Component({
selector: 'user-profile',
template: `
-
-
- Show
-
+ Show
`
})
export class UserProfile { }
-上記の例では、`CustomExpando`は、``が``の直接の子要素ではないため、``を見つけることができません。`descendants: true`を設定することで、クエリが同じテンプレート内のすべての子孫をトラバースするように構成できます。ただし、クエリは、_決して_コンポーネントに侵入して他のテンプレート内の要素をトラバースすることはありません。
+この例では、`CustomExpando`コンポーネントは子`CustomToggle`をクエリし、`ngAfterContentInit`で結果にアクセスしています。
-ビュークエリには、子孫を_常に_トラバースするため、このオプションはありません。
+Angularは、アプリケーションの状態が変化するにつれて`@ContentChild`の結果を最新の状態に保ちます。
-### 要素のインジェクターからの特定の値の読み取り
+**コンテンツクエリの結果は`ngAfterContentInit`ライフサイクルメソッドで使用可能になります。**この時点より前では、値は`undefined`です。コンポーネントライフサイクルの詳細については、[ライフサイクル](guide/components/lifecycle)セクションを参照してください。
-デフォルトでは、クエリロケーターは、検索する要素と取得する値の両方を示します。代わりに、`read`オプションを指定して、ロケーターによって一致する要素から別の値を取得できます。
+`@ContentChildren`デコレーターを使用して、複数の結果をクエリできます。
-```ts
-@Component({...})
-export class CustomExpando {
- @ContentChild(ExpandoContent, {read: TemplateRef}) toggle: TemplateRef;
+
+@Component({
+ selector: 'custom-menu-item',
+ /*...*/
+})
+export class CustomMenuItem {
+ text: string;
+}
+
+@Component({
+ selector: 'custom-menu',
+ /*...*/
+})
+export class CustomMenu {
+ @ContentChildren(CustomMenuItem) items: QueryList;
+
+ ngAfterContentInit() {
+ this.items.forEach(item => {
+ console.log(item.text);
+ });
+ }
+}
+
+@Component({
+ selector: 'user-profile',
+ template: `
+
+ Cheese
+ Tomato
+
+ `
+})
+export class UserProfile { }
+
+
+`@ContentChildren`は、クエリ結果を含む`QueryList`オブジェクトを作成します。`changes`プロパティを使用して、時間の経過とともにクエリ結果の変更を購読できます。
+
+### デコレーターベースのクエリオプション
+
+すべてのクエリデコレーターは、第2引数としてオプションオブジェクトを受け取ります。これらのオプションは、シグナルベースのクエリと同じように動作しますが、下記で説明する点を除きます。
+
+### 静的クエリ
+
+`@ViewChild`と`@ContentChild`デコレーターは、`static`オプションを受け取ります。
+
+```angular-ts
+@Component({
+ selector: 'custom-card',
+ template: 'Visit sunny California!',
+})
+export class CustomCard {
+ @ViewChild(CustomCardHeader, {static: true}) header: CustomCardHeader;
+
+ ngOnInit() {
+ console.log(this.header.text);
+ }
}
```
-上記の例では、`ExpandoContent`ディレクティブを持つ要素を特定し、
-その要素に関連付けられた`TemplateRef`を取得します。
+`static: true`を設定することで、このクエリのターゲットは_常に_存在し、条件付きでレンダリングされないことをAngularに保証します。これにより、`ngOnInit`ライフサイクルメソッドで早く結果を利用できます。
-開発者は、`read`を使用して、`ElementRef`と`TemplateRef`を取得することがほとんどです。
+静的クエリの結果は、初期化後に更新されません。
+
+`static`オプションは、`@ViewChildren`と`@ContentChildren`クエリでは使用できません。
-## QueryList の使用
+### QueryListの使用
`@ViewChildren`と`@ContentChildren`はどちらも、結果のリストを含む`QueryList`オブジェクトを提供します。
-`QueryList`は、`map`、`reduce`、`forEach`などの配列のような方法で結果を操作するための便利なAPIをいくつか提供します。`toArray`を呼び出すことで、現在の結果の配列を取得できます。
+`QueryList`は、`map`、`reduce`、`forEach`など、配列のような方法で結果を操作するための多くの便利なAPIを提供します。`toArray`を呼び出すことで、現在の結果の配列を取得できます。
+
+`changes`プロパティを購読して、結果が変更されるたびに何かを実行できます。
-`changes`プロパティを購読して、結果が変更されるたびに何かを行うことができます。
+## 一般的なクエリの落とし穴
-## クエリの一般的な落とし穴
+クエリを使用する際、一般的な落とし穴により、コードの理解と保守が難しくなる可能性があります。
-クエリを使用する際に、コードの理解と保守を難しくする一般的な落とし穴があります。
+複数のコンポーネント間で共有される状態については、常に単一の真実の源を維持してください。これにより、異なるコンポーネントで状態が繰り返し同期されなくなるシナリオを回避できます。
-複数のコンポーネント間で共有される状態には、常に単一の真実の源を維持します。これにより、異なるコンポーネントで状態が繰り返し使用され、同期が乱れるシナリオを防ぐことができます。
+子コンポーネントに直接状態を書き込むことは避けてください。このパターンは、理解しにくく、[ExpressionChangedAfterItHasBeenChecked](errors/NG0100)エラーが発生しやすい壊れやすいコードにつながる可能性があります。
-子コンポーネントに直接状態を書き込まないでください。このパターンは、理解が難しく、[ExpressionChangedAfterItHasBeenChecked](errors/NG0100)エラーが発生しやすい、もろいコードにつながる可能性があります。
+親コンポーネントまたは祖先コンポーネントに直接状態を書き込むことは決してしないでください。このパターンは、理解しにくく、[ExpressionChangedAfterItHasBeenChecked](errors/NG0100)エラーが発生しやすい壊れやすいコードにつながる可能性があります。
-親または祖先コンポーネントに直接状態を書き込まないでください。このパターンは、理解が難しく、[ExpressionChangedAfterItHasBeenChecked](errors/NG0100)エラーが発生しやすい、もろいコードにつながる可能性があります。
diff --git a/adev-ja/src/content/guide/defer.en.md b/adev-ja/src/content/guide/defer.en.md
deleted file mode 100644
index 21a5537af..000000000
--- a/adev-ja/src/content/guide/defer.en.md
+++ /dev/null
@@ -1,299 +0,0 @@
-# Deferrable Views
-
-## Overview
-
-Deferrable views can be used in component template to defer the loading of select dependencies within that template. Those dependencies include components, directives, and pipes, and any associated CSS. To use this feature, you can declaratively wrap a section of your template in a `@defer` block which specifies the loading conditions.
-
-Deferrable views support a series of [triggers](guide/defer#triggers), [prefetching](guide/defer#prefetching), and several sub blocks used for [placeholder](guide/defer#placeholder), [loading](guide/defer#loading), and [error](guide/defer#error) state management. You can also create custom conditions with [`when`](guide/defer#when) and [`prefetch when`](guide/defer#prefetching).
-
-```angular-html
-@defer {
-
-}
-```
-
-## Why use Deferrable Views?
-
-Deferrable views, also known as `@defer` blocks, are a powerful tool that can be used to reduce the initial bundle size of your application or defer heavy components that may not ever be loaded until a later time. This should result in a faster initial load and an improvement in your Core Web Vitals (CWV) results. Deferring some of your components until later should specifically improve Largest Contentful Paint (LCP) and Time to First Byte (TTFB).
-
-Note: It is highly recommended that any defer loaded component that might result in layout shift once the dependencies have loaded be below the fold or otherwise not yet visible to the user.
-
-## Which dependencies are defer-loadable?
-
-In order for dependencies within a `@defer` block to be deferred, they need to meet two conditions:
-
-1. They must be standalone. Non-standalone dependencies cannot be deferred and will still be eagerly loaded, even inside of `@defer` blocks.
-
-2. They must not be directly referenced from the same file, outside of `@defer` blocks; this includes ViewChild queries.
-
-Transitive dependencies of the components, directives, and pipes used in the defer block can be standalone or NgModule based and will still be deferred.
-
-## Blocks
-
-`@defer` blocks have several sub blocks to allow you to gracefully handle different stages in the deferred loading process.
-
-### `@defer`
-
-The content of the main `@defer` block is the section of content that is lazily loaded. It will not be rendered initially, and all of the content will appear once the specified [trigger](guide/defer#triggers) or `when` condition is met and the dependencies have been fetched. By default, a `@defer` block is triggered when the browser state becomes [idle](guide/defer#on-idle).
-
-### `@placeholder`
-
-By default, defer blocks do not render any content before they are triggered. The `@placeholder` is an optional block that declares content to show before the defer block is triggered. This placeholder content is replaced with the main content once the loading is complete. You can use any content in the placeholder section including plain HTML, components, directives, and pipes; however keep in mind the dependencies of the placeholder block are eagerly loaded.
-
-Note: For the best user experience, you should always specify a `@placeholder` block.
-
-The `@placeholder` block accepts an optional parameter to specify the `minimum` amount of time that this placeholder should be shown. This `minimum` parameter is specified in time increments of milliseconds (ms) or seconds (s). This parameter exists to prevent fast flickering of placeholder content in the case that the deferred dependencies are fetched quickly. The `minimum` timer for the `@placeholder` block begins after the initial render of this `@placeholder` block completes.
-
-```angular-html
-@defer {
-
-} @placeholder (minimum 500ms) {
-
Placeholder content
-}
-```
-
-Note: Certain triggers may require the presence of either a `@placeholder` or a [template reference variable](guide/templates/variables#template-reference-variables) to function. See the [Triggers](guide/defer#triggers) section for more details.
-
-### `@loading`
-
-The `@loading` block is an optional block that allows you to declare content that will be shown during the loading of any deferred dependencies. Its dependences are eagerly loaded (similar to `@placeholder`).
-
-For example, you could show a loading spinner. Once loading has been triggered, the `@loading` block replaces the `@placeholder` block.
-
-The `@loading` block accepts two optional parameters to specify the `minimum` amount of time that this placeholder should be shown and amount of time to wait `after` loading begins before showing the loading template. `minimum` and `after` parameters are specified in time increments of milliseconds (ms) or seconds (s). Just like `@placeholder`, these parameters exist to prevent fast flickering of content in the case that the deferred dependencies are fetched quickly. Both the `minimum` and `after` timers for the `@loading` block begins immediately after the loading has been triggered.
-
-```angular-html
-@defer {
-
-} @loading (after 100ms; minimum 1s) {
-
-}
-```
-
-### `@error`
-
-The `@error` block allows you to declare content that will be shown if deferred loading fails. Similar to `@placeholder` and `@loading`, the dependencies of the `@error` block are eagerly loaded. The `@error` block is optional.
-
-```angular-html
-@defer {
-
-} @error {
-
Failed to load the calendar
-}
-```
-
-## Triggers
-
-When a `@defer` block is triggered, it replaces placeholder content with lazily loaded content. There are two options for configuring when this swap is triggered: `on` and `when`.
-
-
-`on` specifies a trigger condition using a trigger from the list of available triggers below. An example would be on interaction or on viewport.
-
-Multiple event triggers can be defined at once. For example: `on interaction; on timer(5s)` means that the defer block will be triggered if the user interacts with the placeholder, or after 5 seconds.
-
-Note: Multiple `on` triggers are always OR conditions. Similarly, `on` mixed with `when` conditions are also OR conditions.
-
-```angular-html
-@defer (on viewport; on timer(5s)) {
-
-} @placeholder {
-
-}
-```
-
-
-`when` specifies a condition as an expression that returns a boolean. When this expression becomes truthy, the placeholder is swapped with the lazily loaded content (which may be an asynchronous operation if the dependencies need to be fetched).
-
-Note: if the `when` condition switches back to `false`, the defer block is not reverted back to the placeholder. The swap is a one-time operation. If the content within the block should be conditionally rendered, an `if` condition can be used within the block itself.
-
-```angular-html
-@defer (when cond) {
-
-}
-```
-
-You could also use both `when` and `on` together in one statement, and the swap will be triggered if either condition is met.
-
-```angular-html
-@defer (on viewport; when cond) {
-
-} @placeholder {
-
-}
-```
-
-### on idle
-
-`idle` will trigger the deferred loading once the browser has reached an idle state (detected using the `requestIdleCallback` API under the hood). This is the default behavior with a defer block.
-
-### on viewport
-
-`viewport` would trigger the deferred block when the specified content enters the viewport using the [`IntersectionObserver` API](https://developer.mozilla.org/docs/Web/API/Intersection_Observer_API). This could be the placeholder content or an element reference.
-
-By default, the placeholder will act as the element watched for entering viewport as long as it is a single root element node.
-
-```angular-html
-@defer (on viewport) {
-
-} @placeholder {
-
Calendar placeholder
-}
-```
-
-Alternatively, you can specify a [template reference variable](guide/templates/variables#template-reference-variables) in the same template as the `@defer` block as the element that is watched to enter the viewport. This variable is passed in as a parameter on the viewport trigger.
-
-```angular-html
-
Hello!
-
-@defer (on viewport(greeting)) {
-
-}
-```
-
-### on interaction
-
-`interaction` will trigger the deferred block when the user interacts with the specified element through `click` or `keydown` events.
-
-By default, the placeholder will act as the interaction element as long as it is a single root element node.
-
-```angular-html
-@defer (on interaction) {
-
-} @placeholder {
-
Calendar placeholder
-}
-```
-
-Alternatively, you can specify a [template reference variable](guide/templates/variables#template-reference-variables) as the element that triggers interaction. This variable is passed in as a parameter on the interaction trigger.
-
-```angular-html
-
-
-@defer (on interaction(greeting)) {
-
-} @placeholder {
-
Calendar placeholder
-}
-```
-
-### on hover
-
-`hover` triggers deferred loading when the mouse has hovered over the trigger area. Events used for this are `mouseenter` and `focusin`.
-
-By default, the placeholder will act as the hover element as long as it is a single root element node.
-
-```angular-html
-@defer (on hover) {
-
-} @placeholder {
-
Calendar placeholder
-}
-```
-
-Alternatively, you can specify a [template reference variable](guide/templates/variables#template-reference-variables) as the hover element. This variable is passed in as a parameter on the hover trigger.
-
-```angular-html
-
Hello!
-
-@defer (on hover(greeting)) {
-
-} @placeholder {
-
Calendar placeholder
-}
-```
-
-### on immediate
-
-`immediate` triggers the deferred load immediately, meaning once the client has finished rendering, the defer chunk would then start fetching right away.
-
-```angular-html
-@defer (on immediate) {
-
-} @placeholder {
-
Calendar placeholder
-}
-```
-
-### on timer
-
-`timer(x)` would trigger after a specified duration. The duration is required and can be specified in `ms` or `s`.
-
-```angular-html
-@defer (on timer(500ms)) {
-
-}
-```
-
-## Prefetching
-
-`@defer` allows to specify conditions when prefetching of the dependencies should be triggered. You can use a special `prefetch` keyword. `prefetch` syntax works similarly to the main defer conditions, and accepts `when` and/or `on` to declare the trigger.
-
-In this case, `when` and `on` associated with defer controls when to render, and `prefetch when` and `prefetch on` controls when to fetch the resources. This enables more advanced behaviors, such as letting you start to prefetch resources before a user has actually seen or interacted with a defer block, but might interact with it soon, making the resources available faster.
-
-In the example below, the prefetching starts when a browser becomes idle and the contents of the block is rendered on interaction.
-
-```angular-html
-@defer (on interaction; prefetch on idle) {
-
-} @placeholder {
-
-}
-```
-
-## Testing
-
-Angular provides TestBed APIs to simplify the process of testing `@defer` blocks and triggering different states during testing. By default, `@defer` blocks in tests will play through like a defer block would behave in a real application. If you want to manually step through states, you can switch the defer block behavior to `Manual` in the TestBed configuration.
-
-```typescript
-it('should render a defer block in different states', async () => {
- // configures the defer block behavior to start in "paused" state for manual control.
- TestBed.configureTestingModule({deferBlockBehavior: DeferBlockBehavior.Manual});
-
- @Component({
- // ...
- template: `
- @defer {
-
- } @placeholder {
- Placeholder
- } @loading {
- Loading...
- }
- `
- })
- class ComponentA {}
-
- // Create component fixture.
- const componentFixture = TestBed.createComponent(ComponentA);
-
- // Retrieve the list of all defer block fixtures and get the first block.
- const deferBlockFixture = (await componentFixture.getDeferBlocks())[0];
-
- // Renders placeholder state by default.
- expect(componentFixture.nativeElement.innerHTML).toContain('Placeholder');
-
- // Render loading state and verify rendered output.
- await deferBlockFixture.render(DeferBlockState.Loading);
- expect(componentFixture.nativeElement.innerHTML).toContain('Loading');
-
- // Render final state and verify the output.
- await deferBlockFixture.render(DeferBlockState.Complete);
- expect(componentFixture.nativeElement.innerHTML).toContain('large works!');
-});
-```
-
-## Behavior with Server-side rendering (SSR) and Static site generation (SSG)
-
-When rendering an application on the server (either using SSR or SSG), defer blocks always render their `@placeholder` (or nothing if a placeholder is not specified). Triggers are ignored on the server.
-
-## Behavior with `NgModule`
-
-`@defer` blocks can be used in both standalone and NgModule-based components, directives and pipes. You can use standalone and NgModule-based dependencies inside of a `@defer` block, however **only standalone components, directives, and pipes can be deferred**. The NgModule-based dependencies would be included into the eagerly loaded bundle.
-
-## Nested `@defer` blocks and avoiding cascading loads
-
-There are cases where nesting multiple `@defer` blocks may cause cascading requests. An example of this would be when a `@defer` block with an immediate trigger has a nested `@defer` block with another immediate trigger. When you have nested `@defer` blocks, make sure that an inner one has a different set of conditions, so that they don't trigger at the same time, causing cascading requests.
-
-## Avoiding Layout Shifts
-
-It is a recommended best practice to not defer components that will be visible in the user's viewport on initial load. This will negatively affect Core Web Vitals by causing an increase in cumulative layout shift (CLS). If you choose to defer components in this area, it's best to avoid `immediate`, `timer`, `viewport`, and custom `when` conditions that would cause the content to be loaded during the initial render of the page.
diff --git a/adev-ja/src/content/guide/defer.md b/adev-ja/src/content/guide/defer.md
deleted file mode 100644
index 6a1b2f77c..000000000
--- a/adev-ja/src/content/guide/defer.md
+++ /dev/null
@@ -1,299 +0,0 @@
-# 遅延可能なビュー
-
-## 概要
-
-遅延可能なビューは、コンポーネントテンプレート内で、そのテンプレート内の特定の依存関係の読み込みを遅延させるために使用できます。これらの依存関係には、コンポーネントやディレクティブ、パイプおよび関連するCSSが含まれます。この機能を使用するには、テンプレートのセクションを、読み込み条件を指定する `@defer` ブロックで宣言的にラップできます。
-
-遅延可能なビューは一連の[トリガー](guide/defer#triggers)と[プリフェッチ](guide/defer#prefetching)、そして[プレースホルダー](guide/defer#placeholder)や[読み込み中](guide/defer#loading)、[エラー](guide/defer#error)の状態管理に使用されるいくつかのサブブロックをサポートしています。また、[`when`](guide/defer#when)と[`prefetch when`](guide/defer#prefetching)を使用してカスタム条件を作成できます。
-
-```angular-html
-@defer {
-
-}
-```
-
-## 遅延可能なビューを使用する理由
-
-遅延可能なビュー(`@defer` ブロックとも呼ばれます)は、アプリケーションの初期バンドルサイズを削減したり、後で読み込まれる可能性のある重いコンポーネントを遅延させたりするために使用できる強力なツールです。これにより、初期読み込みが高速化され、Core Web Vitals(CWV)の結果が向上するはずです。コンポーネントの一部を後で読み込むように遅延させると、特に最大コンテンツフルペイント(LCP)と最初のバイトまでの時間(TTFB)が向上します。
-
-Note: レイアウトシフトが発生する可能性のある遅延読み込みコンポーネントは、依存関係が読み込まれた後に折り畳み以下にあるか、ユーザーにまだ表示されていない場所に配置することを強くお勧めします。
-
-## どの依存関係が遅延読み込み可能ですか?
-
-`@defer` ブロック内の依存関係が遅延されるためには、次の2つの条件を満たす必要があります。
-
-1. スタンドアロンである必要があります。スタンドアロンではない依存関係は遅延できず、`@defer` ブロック内であっても、引き続き即時的に読み込まれます。
-
-2. 同じファイルから、`@defer` ブロックの外側では直接参照されていない必要があります。これには、ViewChildクエリも含まれます。
-
-遅延ブロックで使用されるコンポーネント、ディレクティブ、パイプの推移的な依存関係は、スタンドアロンまたはNgModuleベースにでき、引き続き遅延されます。
-
-## ブロック
-
-`@defer` ブロックには、遅延読み込みプロセス中のさまざまな段階を適切に処理できるように、いくつかのサブブロックがあります。
-
-### `@defer`
-
-メインの `@defer` ブロックの内容は、遅延読み込みされるコンテンツのセクションです。最初はレンダリングされず、すべてのコンテンツは、指定された[トリガー](guide/defer#triggers)または `when` 条件が満たされ、依存関係がフェッチされると表示されます。デフォルトでは、`@defer` ブロックは、ブラウザの状態が[アイドル状態](guide/defer#on-idle)になるとトリガーされます。
-
-### `@placeholder`
-
-デフォルトでは、遅延ブロックは、トリガーされる前にコンテンツをレンダリングしません。`@placeholder` は、遅延ブロックがトリガーされる前に表示されるコンテンツを宣言するオプションのブロックです。このプレースホルダーコンテンツは、読み込みが完了すると、メインコンテンツに置き換えられます。プレースホルダーセクションには、プレーンHTML、コンポーネント、ディレクティブ、パイプなど、あらゆるコンテンツを使用できます。ただし、プレースホルダーブロックの依存関係は即時的に読み込まれることに注意してください。
-
-Note: 最良のユーザー体験を実現するためには、常に `@placeholder` ブロックを指定する必要があります。
-
-`@placeholder` ブロックは、プレースホルダーを表示する `minimum` 時間を指定するオプションのパラメーターを受け取ります。この `minimum` パラメーターは、ミリ秒 (ms) または秒 (s) の時間増分で指定されます。このパラメーターは、遅延された依存関係がすばやくフェッチされた場合に、プレースホルダーコンテンツの高速なちらつきを防ぐために存在します。`@placeholder` ブロックの `minimum` タイマーは、この `@placeholder` ブロックの初期レンダリングが完了した後に開始されます。
-
-```angular-html
-@defer {
-
-} @placeholder (minimum 500ms) {
-
-
-@defer (on hover(greeting)) {
-
-} @placeholder {
-
カレンダーのプレースホルダー
-}
-```
-
-### on immediate
-
-`immediate` は、遅延読み込みをすぐにトリガーします。つまり、クライアントがレンダリングを完了すると、遅延チャンクがすぐにフェッチを開始します。
-
-```angular-html
-@defer (on immediate) {
-
-} @placeholder {
-
カレンダーのプレースホルダー
-}
-```
-
-### on timer
-
-`timer(x)` は、指定された期間後にトリガーされます。期間は必須であり、`ms` または `s` で指定できます。
-
-```angular-html
-@defer (on timer(500ms)) {
-
-}
-```
-
-## プリフェッチ
-
-`@defer` を使用すると、依存関係のプリフェッチをトリガーする条件を指定できます。`prefetch` キーワードを使用できます。`prefetch` 構文は、メインの遅延条件と同様に機能し、`when` または `on` を受け取ってトリガーを宣言します。
-
-この場合、遅延に関連付けられた `when` と `on` はレンダリングするタイミングを制御し、`prefetch when` と `prefetch on` はリソースをフェッチするタイミングを制御します。これにより、ユーザーが実際に遅延ブロックを見たか、またはインタラクションしないうちにリソースのプリフェッチを開始してすぐにインタラクションする可能性があるため、リソースをより高速に利用できるようにするためのより高度な動作が可能になります。
-
-次の例では、プリフェッチはブラウザがアイドル状態になったときに開始され、ブロックの内容はインタラクション時にレンダリングされます。
-
-```angular-html
-@defer (on interaction; prefetch on idle) {
-
-} @placeholder {
-
-}
-```
-
-## テスト
-
-Angularは、`@defer` ブロックのテストと、テスト中のさまざまな状態のトリガーを簡素化するTestBed APIを提供します。デフォルトでは、テスト内の `@defer` ブロックは、実際のアプリケーションで遅延ブロックが動作するのと同じように動作します。状態を手動でステップ実行する場合は、TestBedの構成で遅延ブロックの動作を `Manual` に切り替えることができます。
-
-```typescript
-it('should render a defer block in different states', async () => {
- // configures the defer block behavior to start in "paused" state for manual control.
- TestBed.configureTestingModule({deferBlockBehavior: DeferBlockBehavior.Manual});
-
- @Component({
- // ...
- template: `
- @defer {
-
- } @placeholder {
- プレースホルダー
- } @loading {
- 読み込み中...
- }
- `
- })
- class ComponentA {}
-
- // Create component fixture.
- const componentFixture = TestBed.createComponent(ComponentA);
-
- // Retrieve the list of all defer block fixtures and get the first block.
- const deferBlockFixture = (await componentFixture.getDeferBlocks())[0];
-
- // Renders placeholder state by default.
- expect(componentFixture.nativeElement.innerHTML).toContain('プレースホルダー');
-
- // Render loading state and verify rendered output.
- await deferBlockFixture.render(DeferBlockState.Loading);
- expect(componentFixture.nativeElement.innerHTML).toContain('読み込み中');
-
- // Render final state and verify the output.
- await deferBlockFixture.render(DeferBlockState.Complete);
- expect(componentFixture.nativeElement.innerHTML).toContain('large works!');
-});
-```
-
-## サーバーサイドレンダリング(SSR)と静的サイト生成(SSG)での動作
-
-サーバーでアプリケーションをレンダリングする場合(SSRまたはSSGを使用)、遅延ブロックは常に `@placeholder` をレンダリングします(プレースホルダーが指定されていない場合は何もレンダリングしません)。トリガーはサーバーでは無視されます。
-
-## `NgModule` での動作
-
-`@defer` ブロックは、スタンドアロンコンポーネントとNgModuleベースのコンポーネント、ディレクティブ、パイプの両方で使用できます。スタンドアロンとNgModuleベースの依存関係を `@defer` ブロック内で使用できますが、**遅延できるのはスタンドアロンコンポーネント、ディレクティブ、パイプのみです**。NgModuleベースの依存関係は、即時的に読み込まれたバンドルに含まれます。
-
-## ネストされた `@defer` ブロックとカスケード読み込みの回避
-
-複数の `@defer` ブロックをネストすると、カスケード要求が発生することがあります。その例としては、immediateトリガーを持つ `@defer` ブロックに、別のimmediateトリガーを持つネストされた `@defer` ブロックがある場合が挙げられます。ネストされた `@defer` ブロックがある場合は、内側のブロックに異なる条件を設定して、同時にトリガーされないようにし、カスケード要求が発生しないようにしてください。
-
-## レイアウトシフトの回避
-
-初期読み込み時にユーザーのビューポートに表示されるコンポーネントは遅延させないことをお勧めします。これにより、累積レイアウトシフト(CLS)が増加し、Core Web Vitalsに悪影響を及ぼします。この領域のコンポーネントを遅延させる場合は、初期レンダリング中にコンテンツが読み込まれる原因となる `immediate`、`timer`、`viewport`、およびカスタム `when` 条件を避けるのが最適です。
diff --git a/adev-ja/src/content/guide/di/dependency-injection.en.md b/adev-ja/src/content/guide/di/dependency-injection.en.md
index b35e72b0d..ce9aeb79a 100644
--- a/adev-ja/src/content/guide/di/dependency-injection.en.md
+++ b/adev-ja/src/content/guide/di/dependency-injection.en.md
@@ -50,9 +50,8 @@ In this case the `HeroService` becomes available to all instances of this compon
For example:
-
+
@Component({
- standalone: true,
selector: 'hero-list',
template: '...',
providers: [HeroService]
diff --git a/adev-ja/src/content/guide/di/dependency-injection.md b/adev-ja/src/content/guide/di/dependency-injection.md
index 3074eb6fb..7b3616dd6 100644
--- a/adev-ja/src/content/guide/di/dependency-injection.md
+++ b/adev-ja/src/content/guide/di/dependency-injection.md
@@ -50,9 +50,8 @@ class HeroService {}
例:
-
+
@Component({
- standalone: true,
selector: 'hero-list',
template: '...',
providers: [HeroService]
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 6ae15ab2a..b3d5da195 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
@@ -816,9 +816,8 @@ Because the injector has only to look at the `ElementInjector` of the `` for the `AnimalService`.
Instead, the injector will begin at the `` `ElementInjector`.
-
+
@Component({
- standalone: true,
selector: 'app-child',
…
viewProviders: [
@@ -853,9 +852,8 @@ If you just use `@Host()` for the injection of `AnimalService`, the result is do
The `ChildComponent` configures the `viewProviders` so that the dog emoji is provided as `AnimalService` value.
You can also see `@Host()` in the constructor:
-
+
@Component({
- standalone: true
selector: 'app-child',
…
viewProviders: [
@@ -886,9 +884,8 @@ export class ChildComponent {
Add a `viewProviders` array with a third animal, hedgehog 🦔, to the `app.component.ts` `@Component()` metadata:
-
+
@Component({
- standalone: true,
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
@@ -1177,4 +1174,4 @@ style RootInjector fill:#BDD7EE,color:#000
-
\ No newline at end of file
+
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 4a61451b3..ea9e2c708 100644
--- a/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md
+++ b/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md
@@ -816,9 +816,8 @@ Emoji from FlowerService: 🌺
`FlowerService` の例と同様に、コンストラクターに `@SkipSelf()` を追加すると、インジェクターは現在の `` の `ElementInjector` を `AnimalService` について検索しません。
代わりに、インジェクターは `` の `ElementInjector` で検索を開始します。
-
+
@Component({
- standalone: true,
selector: 'app-child',
…
viewProviders: [
@@ -853,9 +852,8 @@ Emoji from FlowerService: 🌺
`ChildComponent` は、 `viewProviders` を構成して、犬の絵文字が `AnimalService` 値として提供されるようにします。
また、コンストラクターに `@Host()` があることもわかります。
-
+
@Component({
- standalone: true
selector: 'app-child',
…
viewProviders: [
@@ -886,9 +884,8 @@ export class ChildComponent {
3番目の動物、ハリネズミ 🦔 を含む `viewProviders` 配列を、 `app.component.ts` の `@Component()` メタデータに追加します。
-
+
@Component({
- standalone: true,
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
diff --git a/adev-ja/src/content/guide/di/overview.en.md b/adev-ja/src/content/guide/di/overview.en.md
index 105c02042..d640e1d7b 100644
--- a/adev-ja/src/content/guide/di/overview.en.md
+++ b/adev-ja/src/content/guide/di/overview.en.md
@@ -2,7 +2,7 @@
"DI" is a design pattern and mechanism for creating and delivering some parts of an app to other parts of an app that require them.
-Tip: Check out Angular's [Essentials](essentials/sharing-logic) before diving into this comprehensive guide.
+Tip: Check out Angular's [Essentials](essentials/dependency-injection) before diving into this comprehensive guide.
When you develop a smaller part of your system, like a module or a class, you may need to use features from other classes. For example, you may need an HTTP service to make backend calls. Dependency Injection, or DI, is a design pattern and mechanism for creating and delivering some parts of an application to other parts of an application that require them. Angular supports this design pattern and you can use it in your applications to increase flexibility and modularity.
diff --git a/adev-ja/src/content/guide/di/overview.md b/adev-ja/src/content/guide/di/overview.md
index 13e274ba0..f09899ec0 100644
--- a/adev-ja/src/content/guide/di/overview.md
+++ b/adev-ja/src/content/guide/di/overview.md
@@ -2,7 +2,7 @@
"DI" は、アプリケーションの一部を作成して、それらを必要とするアプリケーションの他の部分に提供するための設計パターンとメカニズムです。
-Tip: この包括的なガイドに取り組む前に、Angularの [基本概念](essentials/sharing-logic) を確認してください。
+Tip: この包括的なガイドに取り組む前に、Angularの [基本概念](essentials/dependency-injection) を確認してください。
モジュールやクラスなどのシステムのより小さな部分を開発する場合、他のクラスの機能を使用する必要がある場合があります。たとえば、バックエンドを呼び出すためにHTTPサービスが必要になる場合があります。依存性の注入 (DI) は、アプリケーションの一部を作成して、それらを必要とするアプリケーションの他の部分に提供するための設計パターンとメカニズムです。Angularはこの設計パターンをサポートしており、アプリケーションでこれを利用することで、柔軟性とモジュール性を高めることができます。
diff --git a/adev-ja/src/content/guide/directives/directive-composition-api.en.md b/adev-ja/src/content/guide/directives/directive-composition-api.en.md
index bfb37cf50..c89832689 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
@@ -16,7 +16,6 @@ works similarly to applying the `MenuBehavior` to the `` element in
```typescript
@Component({
- standalone: true,
selector: 'admin-menu',
template: 'admin-menu.html',
hostDirectives: [MenuBehavior],
@@ -32,7 +31,7 @@ and outputs are not exposed as part of the component's public API. See
**Angular applies host directives statically at compile time.** You cannot dynamically add
directives at runtime.
-**Directives used in `hostDirectives` must be `standalone: true`.**
+**Directives used in `hostDirectives` may not specify `standalone: false`.**
**Angular ignores the `selector` of directives applied in the `hostDirectives` property.**
@@ -44,7 +43,6 @@ in your component's API by expanding the entry in `hostDirectives`:
```typescript
@Component({
- standalone: true,
selector: 'admin-menu',
template: 'admin-menu.html',
hostDirectives: [{
@@ -69,7 +67,6 @@ component:
```typescript
@Component({
- standalone: true,
selector: 'admin-menu',
template: 'admin-menu.html',
hostDirectives: [{
@@ -108,14 +105,12 @@ export class Tooltip { }
// MenuWithTooltip can compose behaviors from multiple other directives
@Directive({
- standalone: true,
hostDirectives: [Tooltip, Menu],
})
export class MenuWithTooltip { }
// CustomWidget can apply the already-composed behaviors from MenuWithTooltip
@Directive({
- standalone: true,
hostDirectives: [MenuWithTooltip],
})
export class SpecializedMenuWithTooltip { }
@@ -132,7 +127,6 @@ The following example shows minimal use of a host directive:
```typescript
@Component({
- standalone: true,
selector: 'admin-menu',
template: 'admin-menu.html',
hostDirectives: [MenuBehavior],
@@ -160,13 +154,11 @@ example.
export class Tooltip { }
@Directive({
- standalone: true,
hostDirectives: [Tooltip],
})
export class CustomTooltip { }
@Directive({
- standalone: true,
hostDirectives: [CustomTooltip],
})
export class EvenMoreCustomTooltip { }
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 e61481e29..a8036dbfc 100644
--- a/adev-ja/src/content/guide/directives/directive-composition-api.md
+++ b/adev-ja/src/content/guide/directives/directive-composition-api.md
@@ -16,7 +16,6 @@ Angularディレクティブは、再利用可能な動作をカプセル化す
```typescript
@Component({
- standalone: true,
selector: 'admin-menu',
template: 'admin-menu.html',
hostDirectives: [MenuBehavior],
@@ -32,7 +31,7 @@ export class AdminMenu { }
**Angularはコンパイル時に静的にホストディレクティブを適用します。**
ランタイム時には動的にディレクティブを追加できません。
-**`hostDirectives` で使用されるディレクティブは `standalone: true` でなければなりません。**
+**`hostDirectives` で使用されるディレクティブは `standalone: false` を指定できません。**
**Angularは `hostDirectives` プロパティで適用されたディレクティブの `selector` を無視します。**
@@ -44,7 +43,6 @@ export class AdminMenu { }
```typescript
@Component({
- standalone: true,
selector: 'admin-menu',
template: 'admin-menu.html',
hostDirectives: [{
@@ -69,7 +67,6 @@ export class AdminMenu { }
```typescript
@Component({
- standalone: true,
selector: 'admin-menu',
template: 'admin-menu.html',
hostDirectives: [{
@@ -108,14 +105,12 @@ export class Tooltip { }
// MenuWithTooltip は、他の複数のディレクティブから動作を構成できます
@Directive({
- standalone: true,
hostDirectives: [Tooltip, Menu],
})
export class MenuWithTooltip { }
// CustomWidget は、すでに構成されている MenuWithTooltip からの動作を適用できます
@Directive({
- standalone: true,
hostDirectives: [MenuWithTooltip],
})
export class SpecializedMenuWithTooltip { }
@@ -132,7 +127,6 @@ export class SpecializedMenuWithTooltip { }
```typescript
@Component({
- standalone: true,
selector: 'admin-menu',
template: 'admin-menu.html',
hostDirectives: [MenuBehavior],
@@ -160,13 +154,11 @@ export class AdminMenu { }
export class Tooltip { }
@Directive({
- standalone: true,
hostDirectives: [Tooltip],
})
export class CustomTooltip { }
@Directive({
- standalone: true,
hostDirectives: [CustomTooltip],
})
export class EvenMoreCustomTooltip { }
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 08be31f42..4b25af1e4 100644
--- a/adev-ja/src/content/guide/directives/structural-directives.en.md
+++ b/adev-ja/src/content/guide/directives/structural-directives.en.md
@@ -79,7 +79,6 @@ Import `TemplateRef`, and `ViewContainerRef`. Inject `TemplateRef` and `ViewCont
import {Directive, TemplateRef, ViewContainerRef} from '@angular/core';
@Directive({
- standalone: true,
selector: '[select]',
})
export class SelectDirective {
diff --git a/adev-ja/src/content/guide/directives/structural-directives.md b/adev-ja/src/content/guide/directives/structural-directives.md
index 4f6be22f3..df56f0da0 100644
--- a/adev-ja/src/content/guide/directives/structural-directives.md
+++ b/adev-ja/src/content/guide/directives/structural-directives.md
@@ -79,7 +79,6 @@ Angularは、ディレクティブクラスを作成し、テンプレートで
import {Directive, TemplateRef, ViewContainerRef} from '@angular/core';
@Directive({
- standalone: true,
selector: '[select]',
})
export class SelectDirective {
diff --git a/adev-ja/src/content/guide/http/making-requests.en.md b/adev-ja/src/content/guide/http/making-requests.en.md
index 810cd99af..c29bb8ba4 100644
--- a/adev-ja/src/content/guide/http/making-requests.en.md
+++ b/adev-ja/src/content/guide/http/making-requests.en.md
@@ -247,7 +247,6 @@ Within a component, you can combine `@if` with the `async` pipe to render the UI
import { AsyncPipe } from '@angular/common';
@Component({
- standalone: true,
imports: [AsyncPipe],
template: `
@if (user$ | async; as user) {
diff --git a/adev-ja/src/content/guide/http/making-requests.md b/adev-ja/src/content/guide/http/making-requests.md
index 5bb94b6e3..b52955944 100644
--- a/adev-ja/src/content/guide/http/making-requests.md
+++ b/adev-ja/src/content/guide/http/making-requests.md
@@ -247,7 +247,6 @@ export class UserService {
import { AsyncPipe } from '@angular/common';
@Component({
- standalone: true,
imports: [AsyncPipe],
template: `
@if (user$ | async; as user) {
diff --git a/adev-ja/src/content/guide/hybrid-rendering.md b/adev-ja/src/content/guide/hybrid-rendering.md
new file mode 100644
index 000000000..7206518bc
--- /dev/null
+++ b/adev-ja/src/content/guide/hybrid-rendering.md
@@ -0,0 +1,322 @@
+# Hybrid rendering
+
+## What is hybrid rendering?
+
+Hybrid rendering combines the benefits of server-side rendering (SSR), pre-rendering (also known as "static site generation" or SSG) and client-side rendering (CSR) to optimize your Angular application. It allows you to render different parts of your application using different strategies, giving you fine-grained control over how your app is delivered to users.
+
+Angular’s new **developer preview** server rendering APIs offer a more efficient and adaptable approach to building modern web applications. These APIs give you complete control over your app’s rendering, allowing for optimizations that enhance performance, Search Engine Optimization (SEO), and overall user experience.
+
+**Benefits of these new APIs:**
+
+- **Greater flexibility:**
+ - Leverage fine-grained control over rendering allows you to optimize for performance and user experience in different parts of your application.
+ - Choose the best rendering strategy for each route, whether it's server-side rendering for fast initial load times, client-side rendering for dynamic interactivity, or a hybrid approach.
+- **Built-in internationalization (i18n):**
+ - Easily adapt your application to different languages and regions with out-of-the-box i18n support.
+- **Environment agnostic:**
+ - Use these APIs with any JavaScript runtime environment, not just Node.js.
+ - Enjoy the benefits of enhanced rendering capabilities regardless of your technology stack.
+- **Seamless dev server integration:**
+ - Take advantage of a smooth and efficient development experience from a fully integrated development server.
+
+This developer preview gives you a first look at these powerful new features. The Angular team encourages you to explore them and provide feedback to help shape the future of Angular server rendering.
+
+## Setting up hybrid rendering
+
+You can create a **new** project with server-side routing with the Angular CLI:
+
+```shell
+ng new --ssr --server-routing
+```
+
+You can also add server-side routing to an existing project with the `ng add` command:
+
+```shell
+ng add @angular/ssr --server-routing
+```
+
+## Server routing
+
+### Configuring server routes
+
+You can create a server route config by declaring an array of [`ServerRoute`](api/ssr/ServerRoute 'API reference') objects. This configuration typically lives in a file named `app.routes.server.ts`.
+
+```typescript
+// app.routes.server.ts
+import { RenderMode, ServerRoute } from '@angular/ssr';
+
+export const serverRoutes: ServerRoute[] = [
+ {
+ path: '', // This renders the "/" route on the client (CSR)
+ renderMode: RenderMode.Client,
+ },
+ {
+ path: 'about', // This page is static, so we prerender it (SSG)
+ renderMode: RenderMode.Prerender,
+ },
+ {
+ path: 'profile', // This page requires user-specific data, so we use SSR
+ renderMode: RenderMode.Server,
+ },
+ {
+ path: '**', // All other routes will be rendered on the server (SSR)
+ renderMode: RenderMode.Server,
+ },
+];
+```
+
+You can add this config to your application using the [`provideServerRoutesConfig`](api/ssr/provideServerRoutesConfig 'API reference') function.
+
+```typescript
+import { provideServerRoutesConfig } from '@angular/ssr';
+import { serverRoutes } from './app.routes.server';
+
+// app.config.server.ts
+const serverConfig: ApplicationConfig = {
+ providers: [
+ provideServerRendering(),
+ provideServerRoutesConfig(serverRoutes),
+ // ... other providers ...
+ ]
+};
+```
+
+When using the [App shell pattern](ecosystem/service-workers/app-shell), you must specify the route to be used as the app shell for client-side rendered routes. To do this, provide an options object with the `appShellRoute` property to [`provideServerRoutesConfig`](api/ssr/provideServerRoutesConfig 'API reference'):
+
+```typescript
+const serverConfig: ApplicationConfig = {
+ providers: [
+ provideServerRoutesConfig(serverRoutes, { appShellRoute: 'shell' }),
+ // ... other providers ...
+ ]
+};
+```
+
+### Rendering modes
+
+The server routing configuration lets you specify how each route in your application should render by setting a [`RenderMode`](api/ssr/RenderMode 'API reference'):
+
+| Rendering mode | Description |
+| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **Server (SSR)** | Renders the application on the server for each request, sending a fully populated HTML page to the browser. See the [Server-Side Rendering (SSR) guide](guide/ssr) for more information. |
+| **Client (CSR)** | Renders the application in the browser. This is the default Angular behavior. |
+| **Prerender (SSG)** | Prerenders the application at build time, generating static HTML files for each route. See the [Prerendering guide](guide/prerendering) for more information. |
+
+#### Choosing a rendering mode
+
+Each rendering mode has different benefits and drawbacks. You can choose rendering modes based on the specific needs of your application.
+
+##### Client-side rendering
+
+Client-side rendering has the simplest development model, as you can write code that assumes it always runs in a web browser. This lets you use a wide range of client-side libraries that also assume they run in a browser.
+
+Client-side rendering generally has worse performance than other rendering modes, as it must download, parse, and execute your page's JavaScript before the user can see any rendered content. If your page fetches more data from the server as it renders, users also have to wait for those additional requests before they can view the complete content.
+
+If your page is indexed by search crawlers, client-side rendering may negatively affect search engine optimization (SEO), as search crawlers have limits to how much JavaScript they execute when indexing a page.
+
+When client-side rendering, the server does not need to do any work to render a page beyond serving static JavaScript assets. You may consider this factor if server cost is a concern.
+
+Applications that support installable, offline experiences with [service workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) can rely on client-side rendering without needing to communicate with a server.
+
+##### Server-side rendering
+
+Server-side rendering offers faster page loads than client-side rendering. Instead of waiting for JavaScript to download and run, the server directly renders an HTML document upon receiving a request from the browser. The user experiences only the latency necessary for the server to fetch data and render the requested page. This mode also eliminates the need for additional network requests from the browser, as your code can fetch data during rendering on the server.
+
+Server-side rendering generally has excellent search engine optimization (SEO), as search crawlers receive a fully rendered HTML document.
+
+Server-side rendering requires you to author code that does not strictly depend on browser APIs and limits your selection of JavaScript libraries that assume they run in a browser.
+
+When server-side rendering, your server runs Angular to produce an HTML response for every request. This additional cost may affect server hosting costs.
+
+##### Build-time prerendering
+
+Prerendering offers faster page loads than both client-side rendering and server-side rendering. Because prerendering creates HTML documents at _build-time_, the server can directly respond to requests with the static HTML document without any additional work.
+
+Prerendering requires that all information necessary to render a page is available at _build-time_. This means that prerendered pages cannot include any data to the specific user loading the page. This means that prerendering is primarily useful for pages that are the same for all users of your application.
+
+Because prerendering occurs at build-time, it may add significant time to your production builds. Using [`getPrerenderParams`](api/ssr/ServerRoutePrerenderWithParams#getPrerenderParams 'API reference') to produce a large number of HTML documents may affect the total file size of your deployments, and thus lead to slower deployments.
+
+It may also add time to your deployments based on the number of static HTML documents included in your build output.
+
+Prerendering generally has excellent search engine optimization (SEO), as search crawlers receive a fully rendered HTML document.
+
+Prerendering requires you to author code that does not strictly depend on browser APIs and limits your selection of JavaScript libraries that assume they run in a browser.
+
+Prerendering incurs extremely little overhead per server request, as your server responds with static HTML documents. Static files are also easily cached by Content Delivery Networks (CDNs), browsers, and intermediate caching layers for even faster subsequent page loads. Deploying static HTML files to a CDN improves scalability by offloading work from your application web server, which is impactful for high-traffic applications.
+
+### Setting headers and status codes
+
+You can set custom headers and status codes for individual server routes using the `headers` and `status` properties in the `ServerRoute` configuration.
+
+```typescript
+// app.routes.server.ts
+import { RenderMode, ServerRoute } from '@angular/ssr';
+
+export const serverRoutes: ServerRoute[] = [
+ {
+ path: 'profile',
+ renderMode: RenderMode.Server,
+ headers: {
+ 'X-My-Custom-Header': 'some-value',
+ },
+ status: 201,
+ },
+ // ... other routes
+];
+```
+
+### Redirects
+
+Angular handles redirects specified by the [`redirectTo`](api/ssr/ServerRoutePrerenderWithParams#getPrerenderParams 'API reference') property in route configurations, differently on the server-side.
+
+**Server-Side Rendering (SSR)**
+Redirects are performed using standard HTTP redirects (e.g., 301, 302) within the server-side rendering process.
+
+**Prerendering (SSG)**
+Redirects are implemented as "soft redirects" using `` tags in the prerendered HTML. This allows for redirects without requiring a round trip to the server.
+
+### Customizing build-time prerendering (SSG)
+
+When using [`RenderMode.Prerender`](api/ssr/RenderMode#Prerender 'API reference'), you can specify several configuration options to customize the prerendering and serving process.
+
+#### Parameterized routes
+
+For each route with [`RenderMode.Prerender`](api/ssr/RenderMode#Prerender 'API reference'), you can specify a [`getPrerenderParams`](api/ssr/ServerRoutePrerenderWithParams#getPrerenderParams 'API reference') function. This function lets you control which specific parameters produce separate prerendered documents.
+
+The [`getPrerenderParams`](api/ssr/ServerRoutePrerenderWithParams#getPrerenderParams 'API reference') function returns a `Promise` that resolves to an array of objects. Each object is a key-value map of route parameter name to value. For example, if you define a route like `posts/:id`, `getPrerenderParams ` could return the array `[{id: 123}, {id: 456}]`, and thus render separate documents for `posts/123` and `posts/456`.
+
+The body of [`getPrerenderParams`](api/ssr/ServerRoutePrerenderWithParams#getPrerenderParams 'API reference') can use Angular's [`inject`](api/core/inject 'API reference') function to inject dependencies and perform any work to determine which routes to prerender. This typically includes making requests to fetch data to construct the array of parameter values.
+
+```typescript
+// app.routes.server.ts
+import { RenderMode, ServerRoute } from '@angular/ssr';
+
+export const serverRoutes: ServerRoute[] = [
+ {
+ path: 'post/:id',
+ renderMode: RenderMode.Prerender,
+ async getPrerenderParams() {
+ const dataService = inject(PostService);
+ const ids = await dataService.getIds(); // Assuming this returns ['1', '2', '3']
+
+ return ids.map(id => ({ id })); // Transforms IDs into an array of objects for prerendering
+
+ // This will prerender the paths: `/post/1`, `/post/2` and `/post/3`
+ },
+ },
+];
+```
+
+Because [`getPrerenderParams`](api/ssr/ServerRoutePrerenderWithParams#getPrerenderParams 'API reference') exclusively applies to [`RenderMode.Prerender`](api/ssr/RenderMode#Prerender 'API reference'), this function always runs at _build-time_. `getPrerenderParams` must not rely on any browser-specific or server-specific APIs for data. If the route does not specify a [`fallback`](api/ssr/ServerRoutePrerenderWithParams#fallback 'API reference') option, the route falls back to [`PrerenderFallback.Server`](api/ssr/PrerenderFallback#Server 'API reference') (SSR) by default.
+
+IMPORTANT: When using [`inject`](api/core/inject 'API reference') inside `getPrerenderParams`, please remember that `inject` must be used synchronously. It cannot be invoked within asynchronous callbacks or following any `await` statements. For more information, refer to [`runInInjectionContext` API reference](api/core/runInInjectionContext).
+
+#### Fallback strategies
+
+When using [`RenderMode.Prerender`](api/ssr/RenderMode#Prerender 'API reference') mode, you can specify a fallback strategy to handle requests for paths that haven't been prerendered.
+
+The available fallback strategies are:
+
+- **Server:** Fallback to server-side rendering. This is the **default** behavior if no `fallback` property is specified.
+- **Client:** Fallback to client-side rendering.
+- **None:** No fallback. Angular will not handle requests for paths that are not prerendered.
+
+```typescript
+// app.routes.server.ts
+import { RenderMode, PrerenderFallback, ServerRoute } from '@angular/ssr';
+
+export const serverRoutes: ServerRoute[] = [
+ {
+ path: 'post/:id',
+ renderMode: RenderMode.Prerender,
+ fallback: PrerenderFallback.Client, // Fallback to CSR if not prerendered
+ async getPrerenderParams() {
+ // This function returns an array of objects representing prerendered posts at the paths:
+ // `/post/1`, `/post/2`, and `/post/3`.
+ // The path `/post/4` will utilize the fallback behavior if it's requested.
+ return [{ id: 1 }, { id: 2 }, { id: 3 }];
+ },
+ },
+];
+```
+
+## Accessing Request and Response via DI
+
+The `@angular/core` package provides several tokens for interacting with the server-side rendering environment. These tokens give you access to crucial information and objects within your Angular application during SSR.
+
+- **[`REQUEST`](api/core/REQUEST 'API reference'):** Provides access to the current request object, which is of type [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) from the Web API. This allows you to access headers, cookies, and other request information.
+- **[`RESPONSE_INIT`](api/core/RESPONSE_INIT 'API reference'):** Provides access to the response initialization options, which is of type [`ResponseInit`](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#parameters) from the Web API. This allows you to set headers and the status code for the response dynamically. Use this token to set headers or status codes that need to be determined at runtime.
+- **[`REQUEST_CONTEXT`](api/core/REQUEST_CONTEXT 'API reference'):** Provides access to additional context related to the current request. This context can be passed as the second parameter of the [`handle`](api/ssr/AngularAppEngine#handle 'API reference') function. Typically, this is used to provide additional request-related information that is not part of the standard Web API.
+
+```angular-ts
+import { inject, REQUEST } from '@angular/core';
+
+@Component({
+ selector: 'app-my-component',
+ template: `
My Component
`,
+})
+export class MyComponent {
+ constructor() {
+ const request = inject(REQUEST);
+ console.log(request?.url);
+ }
+}
+```
+
+IMPORTANT: The above tokens will be `null` in the following scenarios:
+
+- During the build processes.
+- When the application is rendered in the browser (client-side rendering).
+- When performing static site generation (SSG).
+- During route extraction in development (at the time of the request).
+
+## Configuring a non-Node.js Server
+
+The `@angular/ssr` provides essential APIs for server-side rendering your Angular application on platforms other than Node.js. It leverages the standard [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) objects from the Web API, enabling you to integrate Angular SSR into various server environments. For detailed information and examples, refer to the [`@angular/ssr` API reference](api/ssr/node/AngularAppEngine).
+
+```typescript
+// server.ts
+import { AngularAppEngine, createRequestHandler } from '@angular/ssr';
+
+const angularApp = new AngularAppEngine();
+
+/**
+ * This is a request handler used by the Angular CLI (dev-server and during build).
+ */
+const reqHandler = createRequestHandler(async (req: Request) => {
+ const res: Response|null = await angularApp.render(req);
+
+ // ...
+});
+```
+
+## Configuring a Node.js Server
+
+The `@angular/ssr/node` extends `@angular/ssr` specifically for Node.js environments. It provides APIs that make it easier to implement server-side rendering within your Node.js application. For a complete list of functions and usage examples, refer to the [`@angular/ssr/node` API reference](api/ssr/node/AngularNodeAppEngine) API reference.
+
+```typescript
+// server.ts
+import { AngularNodeAppEngine, createNodeRequestHandler, writeResponseToNodeResponse } from '@angular/ssr/node';
+import express from 'express';
+
+const app = express();
+const angularApp = new AngularNodeAppEngine();
+
+app.get('*', (req, res, next) =>
+ angularApp
+ .handle(req)
+ .then(response => {
+ if (response) {
+ writeResponseToNodeResponse(response, res);
+ } else {
+ next(); // Pass control to the next middleware
+ }
+ })
+ .catch(next);
+});
+
+/**
+ * The request handler used by the Angular CLI (dev-server and during build).
+ */
+export const reqHandler = createNodeRequestHandler(app);
+```v
diff --git a/adev-ja/src/content/guide/hydration.en.md b/adev-ja/src/content/guide/hydration.en.md
index 966d16ae2..b5baa63d9 100644
--- a/adev-ja/src/content/guide/hydration.en.md
+++ b/adev-ja/src/content/guide/hydration.en.md
@@ -75,8 +75,6 @@ bootstrapApplication(App, {
});
```
-IMPORTANT: the Event Replay feature is currently in [Developer Preview](/reference/releases#developer-preview).
-
## Constraints
Hydration imposes a few constraints on your application that are not present without hydration enabled. Your application must have the same generated DOM structure on both the server and the client. The process of hydration expects the DOM tree to have the same structure in both places. This also includes whitespaces and comment nodes that Angular produces during the rendering on the server. Those whitespaces and nodes must be present in the HTML generated by the server-side rendering process.
@@ -99,10 +97,10 @@ There are a few cases where if you have a component template that does not have
As an example, here are some of the most common cases of this issue.
-* `