From c6eb47a32e81c2a9c77d15d681e06de92b5b92b3 Mon Sep 17 00:00:00 2001 From: Suguru Inatomi Date: Thu, 23 Jan 2025 09:28:15 +0900 Subject: [PATCH] feat: update origin 19.1 (#1009) * feat: update origin to 19.1.2 * chore: migrate untranslated files * chore: migrate small changes * migrate navigation data * chore: fix git patches * chore: address lint errors --- .textlintrc | 4 +- .../app/features/update/recommendations.en.ts | 25 +- .../app/features/update/recommendations.ts | 25 +- .../features/update/update.component.en.ts | 9 +- .../app/features/update/update.component.ts | 8 + adev-ja/src/app/sub-navigation-data.en.ts | 288 +++--------------- adev-ja/src/app/sub-navigation-data.ts | 288 +++--------------- adev-ja/src/content/cli/index.md | 2 +- .../ecosystem/rxjs-interop/output-interop.md | 4 +- .../ecosystem/rxjs-interop/signals-interop.md | 1 + .../guide/animations/complex-sequences.md | 3 +- .../components/anatomy-of-components.en.md | 2 +- .../src/content/guide/components/inputs.en.md | 2 +- .../src/content/guide/components/inputs.md | 4 +- .../content/guide/components/lifecycle.en.md | 2 +- .../src/content/guide/components/lifecycle.md | 2 +- .../content/guide/components/queries.en.md | 2 +- .../guide/di/dependency-injection.en.md | 2 +- .../content/guide/di/dependency-injection.md | 2 +- .../hierarchical-dependency-injection.en.md | 6 +- .../di/hierarchical-dependency-injection.md | 6 +- .../content/guide/directives/overview.en.md | 2 + .../src/content/guide/directives/overview.md | 2 + adev-ja/src/content/guide/elements.md | 7 + .../src/content/guide/forms/overview.en.md | 10 +- adev-ja/src/content/guide/forms/overview.md | 10 +- .../content/guide/http/making-requests.en.md | 4 +- .../src/content/guide/http/making-requests.md | 4 +- .../src/content/guide/hybrid-rendering.en.md | 9 +- adev-ja/src/content/guide/hybrid-rendering.md | 4 +- adev-ja/src/content/guide/hydration.en.md | 14 +- adev-ja/src/content/guide/hydration.md | 54 ++-- adev-ja/src/content/guide/i18n/deploy.md | 14 +- .../src/content/guide/ngmodules/overview.md | 6 +- adev-ja/src/content/guide/prerendering.en.md | 2 +- adev-ja/src/content/guide/prerendering.md | 2 +- .../guide/routing/common-router-tasks.en.md | 44 +-- .../guide/routing/common-router-tasks.md | 44 +-- .../content/guide/signals/linked-signal.en.md | 31 +- .../content/guide/signals/linked-signal.md | 43 ++- .../src/content/guide/signals/resource.en.md | 13 +- adev-ja/src/content/guide/signals/resource.md | 9 +- adev-ja/src/content/guide/ssr.en.md | 4 +- adev-ja/src/content/guide/ssr.md | 2 +- .../guide/templates/control-flow.en.md | 2 + .../content/guide/templates/control-flow.md | 2 + .../src/content/guide/templates/defer.en.md | 14 +- adev-ja/src/content/guide/templates/defer.md | 122 ++++---- .../content/guide/templates/overview.en.md | 2 +- .../src/content/guide/templates/pipes.en.md | 16 +- adev-ja/src/content/guide/templates/pipes.md | 16 +- .../testing/component-harnesses-overview.md | 30 ++ ...omponent-harnesses-testing-environments.md | 59 ++++ .../guide/testing/components-scenarios.en.md | 2 +- .../guide/testing/components-scenarios.md | 2 +- .../testing/creating-component-harnesses.md | 276 +++++++++++++++++ .../testing/using-component-harnesses.md | 207 +++++++++++++ .../content/guide/testing/utility-apis.en.md | 2 +- .../src/content/guide/testing/utility-apis.md | 2 +- .../essentials/dependency-injection.en.md | 2 +- .../introduction/essentials/templates.en.md | 6 +- .../introduction/essentials/templates.md | 6 +- .../configs/angular-compiler-options.md | 4 + .../content/reference/errors/NG01203.en.md | 2 +- .../src/content/reference/errors/NG01203.md | 2 +- .../src/content/reference/errors/NG0750.md | 6 + .../src/content/reference/errors/NG0913.en.md | 5 +- .../src/content/reference/errors/NG0913.md | 5 +- .../content/reference/errors/overview.en.md | 3 +- .../src/content/reference/errors/overview.md | 1 + .../migrations/cleanup-unused-imports.md | 38 +++ .../content/reference/migrations/outputs.md | 96 ++++++ .../content/reference/migrations/overview.md | 10 +- .../reference/migrations/standalone.md | 17 +- adev-ja/src/content/reference/releases.en.md | 12 +- adev-ja/src/content/reference/releases.md | 12 +- adev-ja/src/content/reference/roadmap.en.md | 4 +- adev-ja/src/content/reference/roadmap.md | 4 +- adev-ja/src/content/reference/versions.en.md | 1 + adev-ja/src/content/reference/versions.md | 1 + .../tools/cli/build-system-migration.md | 35 +-- adev-ja/src/content/tools/cli/build.md | 2 +- adev-ja/src/content/tools/cli/deployment.md | 14 +- adev-ja/src/content/tools/cli/serve.md | 2 +- .../content/tools/cli/template-typecheck.md | 2 +- adev-ja/src/content/tools/language-service.md | 4 +- .../tools/libraries/angular-package-format.md | 6 +- .../tools/libraries/creating-libraries.md | 2 +- .../tutorials/first-app/intro/README.md | 1 + .../07-dynamic-template-values/README.md | 8 +- origin | 2 +- tools/adev-patches/add-global-styles.patch | 18 +- tools/adev-patches/localize-home.patch | 4 +- .../adev-patches/replace-canonical-host.patch | 4 +- .../set-current-major-verion.patch | 8 +- .../translate-top-level-banner.patch | 11 +- .../translate-tutorial-label.patch | 8 +- 97 files changed, 1261 insertions(+), 882 deletions(-) create mode 100644 adev-ja/src/content/guide/testing/component-harnesses-overview.md create mode 100644 adev-ja/src/content/guide/testing/component-harnesses-testing-environments.md create mode 100644 adev-ja/src/content/guide/testing/creating-component-harnesses.md create mode 100644 adev-ja/src/content/guide/testing/using-component-harnesses.md create mode 100644 adev-ja/src/content/reference/errors/NG0750.md create mode 100644 adev-ja/src/content/reference/migrations/cleanup-unused-imports.md create mode 100644 adev-ja/src/content/reference/migrations/outputs.md diff --git a/.textlintrc b/.textlintrc index 45af8b558..df6ba601c 100644 --- a/.textlintrc +++ b/.textlintrc @@ -21,6 +21,7 @@ "preset-ja-technical-writing": { "sentence-length": false, "max-comma": false, + "max-ten": false, "no-mix-dearu-desumasu": { "preferInList": "" }, @@ -42,7 +43,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 ccc6fe0e8..0ea9a1169 100644 --- a/adev-ja/src/app/features/update/recommendations.en.ts +++ b/adev-ja/src/app/features/update/recommendations.en.ts @@ -1,3 +1,11 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + export enum ApplicationComplexity { Basic = 1, Medium = 2, @@ -2397,7 +2405,22 @@ 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: + "In the application's project directory, run `ng update @angular/core@19 @angular/cli@19` to update your application to Angular v19.", + level: ApplicationComplexity.Basic, + necessaryAsOf: 1900, + possibleIn: 1900, + step: '19.0.0_ng_update', + }, + { + possibleIn: 1900, + necessaryAsOf: 1900, + level: ApplicationComplexity.Basic, + material: true, + step: 'update @angular/material', + action: 'Run `ng update @angular/material@19`.', + }, { 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.', diff --git a/adev-ja/src/app/features/update/recommendations.ts b/adev-ja/src/app/features/update/recommendations.ts index e719b4b4f..5ec124e4d 100644 --- a/adev-ja/src/app/features/update/recommendations.ts +++ b/adev-ja/src/app/features/update/recommendations.ts @@ -1,3 +1,11 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + export enum ApplicationComplexity { Basic = 1, Medium = 2, @@ -2397,7 +2405,22 @@ export const RECOMMENDATIONS: Step[] = [ action: '`ComponentFixture.autoDetect` が `ApplicationRef.tick` 内のフィクスチャの変更検出を実行するようになったため、`ComponentFixture.autoDetect` を使用しているときに変更検出の実行順序に依存しているテストがあると、テストに失敗することがあります。たとえば、これによってテストフィクスチャは、これまではその逆であったかもしれませんが、作成するダイアログの前にリフレッシュされます。', }, - + { + action: + "アプリケーションのプロジェクトディレクトリで、`ng update @angular/core@19 @angular/cli@19` を実行し、アプリケーションをAngular v19にアップデートしてください。", + level: ApplicationComplexity.Basic, + necessaryAsOf: 1900, + possibleIn: 1900, + step: '19.0.0_ng_update', + }, + { + possibleIn: 1900, + necessaryAsOf: 1900, + level: ApplicationComplexity.Basic, + material: true, + step: '@angular/material をアップデートしてください。', + action: 'Run `ng update @angular/material@19`.', + }, { action: 'Angularディレクティブ、コンポーネント、パイプはデフォルトでスタンドアロンになりました。現在NgModuleで宣言されている宣言には "standalone: false" を指定してください。Angular CLIは自動的にコードを更新します。', 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 d82843a76..4adb7ea39 100644 --- a/adev-ja/src/app/features/update/update.component.en.ts +++ b/adev-ja/src/app/features/update/update.component.en.ts @@ -1,3 +1,11 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + import {ChangeDetectionStrategy, Component, HostListener, inject} from '@angular/core'; import {Step, RECOMMENDATIONS} from './recommendations'; import {Clipboard} from '@angular/cdk/clipboard'; @@ -30,7 +38,6 @@ interface Option { CdkMenuModule, IconComponent, ], - standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) export default class AppComponent { diff --git a/adev-ja/src/app/features/update/update.component.ts b/adev-ja/src/app/features/update/update.component.ts index 6ecf6a5d2..d6562c88b 100644 --- a/adev-ja/src/app/features/update/update.component.ts +++ b/adev-ja/src/app/features/update/update.component.ts @@ -1,3 +1,11 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + import {ChangeDetectionStrategy, Component, HostListener, inject} from '@angular/core'; import {Step, RECOMMENDATIONS} from './recommendations'; import {Clipboard} from '@angular/cdk/clipboard'; diff --git a/adev-ja/src/app/sub-navigation-data.en.ts b/adev-ja/src/app/sub-navigation-data.en.ts index cad8b3168..2aa7db92b 100644 --- a/adev-ja/src/app/sub-navigation-data.en.ts +++ b/adev-ja/src/app/sub-navigation-data.en.ts @@ -12,6 +12,8 @@ import {NavigationItem} from '@angular/docs'; 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 ERRORS_NAV_DATA from '../../src/assets/content/reference/errors/routes.json'; +import EXT_DIAGNOSTICS_NAV_DATA from '../../src/assets/content/reference/extended-diagnostics/routes.json'; import {DefaultPage} from './core/enums/pages'; import {getApiNavigationItems} from './features/references/helpers/manifest.helper'; @@ -90,12 +92,12 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [ contentPath: 'guide/signals/overview', }, { - label: 'linkedSignal', + label: 'Dependent state with linkedSignal', path: 'guide/signals/linked-signal', contentPath: 'guide/signals/linked-signal', }, { - label: 'Resource', + label: 'Async reactivity with resources', path: 'guide/signals/resource', contentPath: 'guide/signals/resource', }, @@ -499,6 +501,26 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'guide/testing/utility-apis', contentPath: 'guide/testing/utility-apis', }, + { + label: 'Component harnesses overview', + path: 'guide/testing/component-harnesses-overview', + contentPath: 'guide/testing/component-harnesses-overview', + }, + { + label: 'Using component harnesses in tests', + path: 'guide/testing/using-component-harnesses', + contentPath: 'guide/testing/using-component-harnesses', + }, + { + label: 'Creating harnesses for your components', + path: 'guide/testing/creating-component-harnesses', + contentPath: 'guide/testing/creating-component-harnesses', + }, + { + label: 'Adding harness support for additional testing environments', + path: 'guide/testing/component-harnesses-testing-environments', + contentPath: 'guide/testing/component-harnesses-testing-environments', + }, ], }, { @@ -1110,201 +1132,7 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'errors', contentPath: 'reference/errors/overview', }, - { - label: 'NG0100: Expression Changed After Checked', - path: 'errors/NG0100', - contentPath: 'reference/errors/NG0100', - }, - { - label: 'NG01101: Wrong Async Validator Return Type', - path: 'errors/NG01101', - contentPath: 'reference/errors/NG01101', - }, - { - label: 'NG01203: Missing value accessor', - path: 'errors/NG01203', - contentPath: 'reference/errors/NG01203', - }, - { - label: 'NG0200: Circular Dependency in DI', - path: 'errors/NG0200', - contentPath: 'reference/errors/NG0200', - }, - { - label: 'NG0201: No Provider Found', - path: 'errors/NG0201', - contentPath: 'reference/errors/NG0201', - }, - { - label: 'NG0203: `inject()` must be called from an injection context', - path: 'errors/NG0203', - contentPath: 'reference/errors/NG0203', - }, - { - label: 'NG0209: Invalid multi provider', - path: 'errors/NG0209', - contentPath: 'reference/errors/NG0209', - }, - { - label: 'NG02200: Missing Iterable Differ', - path: 'errors/NG02200', - contentPath: 'reference/errors/NG02200', - }, - { - label: 'NG02800: JSONP support in HttpClient configuration', - path: 'errors/NG02800', - contentPath: 'reference/errors/NG02800', - }, - { - label: 'NG0300: Selector Collision', - path: 'errors/NG0300', - contentPath: 'reference/errors/NG0300', - }, - { - label: 'NG0301: Export Not Found', - path: 'errors/NG0301', - contentPath: 'reference/errors/NG0301', - }, - { - label: 'NG0302: Pipe Not Found', - path: 'errors/NG0302', - contentPath: 'reference/errors/NG0302', - }, - { - label: `NG0403: Bootstrapped NgModule doesn't specify which component to initialize`, - path: 'errors/NG0403', - contentPath: 'reference/errors/NG0403', - }, - { - label: 'NG0500: Hydration Node Mismatch', - path: 'errors/NG0500', - contentPath: 'reference/errors/NG0500', - }, - { - label: 'NG0501: Hydration Missing Siblings', - path: 'errors/NG0501', - contentPath: 'reference/errors/NG0501', - }, - { - label: 'NG0502: Hydration Missing Node', - path: 'errors/NG0502', - contentPath: 'reference/errors/NG0502', - }, - { - label: 'NG0503: Hydration Unsupported Projection of DOM Nodes', - path: 'errors/NG0503', - contentPath: 'reference/errors/NG0503', - }, - { - label: 'NG0504: Skip hydration flag is applied to an invalid node', - path: 'errors/NG0504', - contentPath: 'reference/errors/NG0504', - }, - { - label: 'NG0505: No hydration info in server response', - path: 'errors/NG0505', - contentPath: 'reference/errors/NG0505', - }, - { - label: 'NG0506: NgZone remains unstable', - path: 'errors/NG0506', - contentPath: 'reference/errors/NG0506', - }, - { - label: 'NG0507: HTML content was altered after server-side rendering', - path: 'errors/NG0507', - contentPath: 'reference/errors/NG0507', - }, - { - label: 'NG0602: Disallowed function call inside reactive context', - path: 'errors/NG0602', - contentPath: 'reference/errors/NG0602', - }, - { - label: 'NG05104: Root element was not found', - path: 'errors/NG05104', - contentPath: 'reference/errors/NG05104', - }, - { - label: 'NG0910: Unsafe bindings on an iframe element', - path: 'errors/NG0910', - contentPath: 'reference/errors/NG0910', - }, - { - label: 'NG0912: Component ID generation collision', - path: 'errors/NG0912', - contentPath: 'reference/errors/NG0912', - }, - { - label: 'NG0913: Runtime Performance Warnings', - path: 'errors/NG0913', - contentPath: 'reference/errors/NG0913', - }, - { - label: 'NG0950: Required input is accessed before a value is set.', - path: 'errors/NG0950', - contentPath: 'reference/errors/NG0950', - }, - { - label: 'NG0951: Child query result is required but no value is available.', - path: 'errors/NG0951', - contentPath: 'reference/errors/NG0951', - }, - { - label: 'NG0955: Track expression resulted in duplicated keys for a given collection', - path: 'errors/NG0955', - contentPath: 'reference/errors/NG0955', - }, - { - label: 'NG0956: Tracking expression caused re-creation of the DOM structure', - path: 'errors/NG0956', - contentPath: 'reference/errors/NG0956', - }, - { - label: 'NG1001: Argument Not Literal', - path: 'errors/NG1001', - contentPath: 'reference/errors/NG1001', - }, - { - label: 'NG2003: Missing Token', - path: 'errors/NG2003', - contentPath: 'reference/errors/NG2003', - }, - { - label: 'NG2009: Invalid Shadow DOM selector', - path: 'errors/NG2009', - contentPath: 'reference/errors/NG2009', - }, - { - label: 'NG3003: Import Cycle Detected', - path: 'errors/NG3003', - contentPath: 'reference/errors/NG3003', - }, - { - label: 'NG05000: Hydration with unsupported Zone.js instance.', - path: 'errors/NG05000', - contentPath: 'reference/errors/NG05000', - }, - { - label: 'NG6100: NgModule.id Set to module.id anti-pattern', - path: 'errors/NG6100', - contentPath: 'reference/errors/NG6100', - }, - { - label: 'NG8001: Invalid Element', - path: 'errors/NG8001', - contentPath: 'reference/errors/NG8001', - }, - { - label: 'NG8002: Invalid Attribute', - path: 'errors/NG8002', - contentPath: 'reference/errors/NG8002', - }, - { - label: 'NG8003: Missing Reference Target', - path: 'errors/NG8003', - contentPath: 'reference/errors/NG8003', - }, + ...ERRORS_NAV_DATA, ], }, { @@ -1315,61 +1143,7 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'extended-diagnostics', contentPath: 'reference/extended-diagnostics/overview', }, - { - label: 'NG8101: Invalid Banana-in-Box', - path: 'extended-diagnostics/NG8101', - contentPath: 'reference/extended-diagnostics/NG8101', - }, - { - label: 'NG8102: Nullish coalescing not nullable', - path: 'extended-diagnostics/NG8102', - contentPath: 'reference/extended-diagnostics/NG8102', - }, - { - label: 'NG8103: Missing control flow directive', - path: 'extended-diagnostics/NG8103', - contentPath: 'reference/extended-diagnostics/NG8103', - }, - { - label: 'NG8104: Text attribute not binding', - path: 'extended-diagnostics/NG8104', - contentPath: 'reference/extended-diagnostics/NG8104', - }, - { - label: 'NG8105: Missing `let` keyword in an *ngFor expression', - path: 'extended-diagnostics/NG8105', - contentPath: 'reference/extended-diagnostics/NG8105', - }, - { - label: 'NG8106: Suffix not supported', - path: 'extended-diagnostics/NG8106', - contentPath: 'reference/extended-diagnostics/NG8106', - }, - { - label: 'NG8107: Optional chain not nullable', - path: 'extended-diagnostics/NG8107', - contentPath: 'reference/extended-diagnostics/NG8107', - }, - { - label: 'NG8108: ngSkipHydration should be a static attribute', - path: 'extended-diagnostics/NG8108', - contentPath: 'reference/extended-diagnostics/NG8108', - }, - { - label: 'NG8109: Signals must be invoked in template interpolations', - path: 'extended-diagnostics/NG8109', - contentPath: 'reference/extended-diagnostics/NG8109', - }, - { - label: 'NG8111: Functions must be invoked in event bindings', - path: 'extended-diagnostics/NG8111', - contentPath: 'reference/extended-diagnostics/NG8111', - }, - { - label: 'NG8113: Unused Standalone Imports', - path: 'extended-diagnostics/NG8113', - contentPath: 'reference/extended-diagnostics/NG8113', - }, + ...EXT_DIAGNOSTICS_NAV_DATA, ], }, { @@ -1444,11 +1218,21 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'reference/migrations/signal-inputs', contentPath: 'reference/migrations/signal-inputs', }, + { + label: 'Outputs', + path: 'reference/migrations/outputs', + contentPath: 'reference/migrations/outputs', + }, { label: 'Signal queries', path: 'reference/migrations/signal-queries', contentPath: 'reference/migrations/signal-queries', }, + { + label: 'Clean up unused imports', + path: 'reference/migrations/cleanup-unused-imports', + contentPath: 'reference/migrations/cleanup-unused-imports', + }, ], }, ]; diff --git a/adev-ja/src/app/sub-navigation-data.ts b/adev-ja/src/app/sub-navigation-data.ts index e8c5bb9cf..cdaa87120 100644 --- a/adev-ja/src/app/sub-navigation-data.ts +++ b/adev-ja/src/app/sub-navigation-data.ts @@ -12,6 +12,8 @@ import {NavigationItem} from '@angular/docs'; 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 ERRORS_NAV_DATA from '../../src/assets/content/reference/errors/routes.json'; +import EXT_DIAGNOSTICS_NAV_DATA from '../../src/assets/content/reference/extended-diagnostics/routes.json'; import {DefaultPage} from './core/enums/pages'; import {getApiNavigationItems} from './features/references/helpers/manifest.helper'; @@ -90,12 +92,12 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [ contentPath: 'guide/signals/overview', }, { - label: 'linkedSignal', + label: 'linkedSignalによる派生状態', path: 'guide/signals/linked-signal', contentPath: 'guide/signals/linked-signal', }, { - label: 'Resource', + label: 'resourceによる非同期りアクティビティ', path: 'guide/signals/resource', contentPath: 'guide/signals/resource', }, @@ -499,6 +501,26 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'guide/testing/utility-apis', contentPath: 'guide/testing/utility-apis', }, + { + label: 'コンポーネントハーネスの概要', + path: 'guide/testing/component-harnesses-overview', + contentPath: 'guide/testing/component-harnesses-overview', + }, + { + label: 'テストでコンポーネントハーネスを使う', + path: 'guide/testing/using-component-harnesses', + contentPath: 'guide/testing/using-component-harnesses', + }, + { + label: 'コンポーネントハーネスを作成する', + path: 'guide/testing/creating-component-harnesses', + contentPath: 'guide/testing/creating-component-harnesses', + }, + { + label: 'テスト環境にハーネスサポートを追加する', + path: 'guide/testing/component-harnesses-testing-environments', + contentPath: 'guide/testing/component-harnesses-testing-environments', + }, ], }, { @@ -1118,201 +1140,7 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'errors', contentPath: 'reference/errors/overview', }, - { - label: 'NG0100: Expression Changed After Checked', - path: 'errors/NG0100', - contentPath: 'reference/errors/NG0100', - }, - { - label: 'NG01101: Wrong Async Validator Return Type', - path: 'errors/NG01101', - contentPath: 'reference/errors/NG01101', - }, - { - label: 'NG01203: Missing value accessor', - path: 'errors/NG01203', - contentPath: 'reference/errors/NG01203', - }, - { - label: 'NG0200: Circular Dependency in DI', - path: 'errors/NG0200', - contentPath: 'reference/errors/NG0200', - }, - { - label: 'NG0201: No Provider Found', - path: 'errors/NG0201', - contentPath: 'reference/errors/NG0201', - }, - { - label: 'NG0203: `inject()` must be called from an injection context', - path: 'errors/NG0203', - contentPath: 'reference/errors/NG0203', - }, - { - label: 'NG0209: Invalid multi provider', - path: 'errors/NG0209', - contentPath: 'reference/errors/NG0209', - }, - { - label: 'NG02200: Missing Iterable Differ', - path: 'errors/NG02200', - contentPath: 'reference/errors/NG02200', - }, - { - label: 'NG02800: JSONP support in HttpClient configuration', - path: 'errors/NG02800', - contentPath: 'reference/errors/NG02800', - }, - { - label: 'NG0300: Selector Collision', - path: 'errors/NG0300', - contentPath: 'reference/errors/NG0300', - }, - { - label: 'NG0301: Export Not Found', - path: 'errors/NG0301', - contentPath: 'reference/errors/NG0301', - }, - { - label: 'NG0302: Pipe Not Found', - path: 'errors/NG0302', - contentPath: 'reference/errors/NG0302', - }, - { - label: `NG0403: Bootstrapped NgModule doesn't specify which component to initialize`, - path: 'errors/NG0403', - contentPath: 'reference/errors/NG0403', - }, - { - label: 'NG0500: Hydration Node Mismatch', - path: 'errors/NG0500', - contentPath: 'reference/errors/NG0500', - }, - { - label: 'NG0501: Hydration Missing Siblings', - path: 'errors/NG0501', - contentPath: 'reference/errors/NG0501', - }, - { - label: 'NG0502: Hydration Missing Node', - path: 'errors/NG0502', - contentPath: 'reference/errors/NG0502', - }, - { - label: 'NG0503: Hydration Unsupported Projection of DOM Nodes', - path: 'errors/NG0503', - contentPath: 'reference/errors/NG0503', - }, - { - label: 'NG0504: Skip hydration flag is applied to an invalid node', - path: 'errors/NG0504', - contentPath: 'reference/errors/NG0504', - }, - { - label: 'NG0505: No hydration info in server response', - path: 'errors/NG0505', - contentPath: 'reference/errors/NG0505', - }, - { - label: 'NG0506: NgZone remains unstable', - path: 'errors/NG0506', - contentPath: 'reference/errors/NG0506', - }, - { - label: 'NG0507: HTML content was altered after server-side rendering', - path: 'errors/NG0507', - contentPath: 'reference/errors/NG0507', - }, - { - label: 'NG0602: HTML content was altered after server-side rendering', - path: 'errors/NG0602', - contentPath: 'reference/errors/NG0602', - }, - { - label: 'NG05104: Root element was not found', - path: 'errors/NG05104', - contentPath: 'reference/errors/NG05104', - }, - { - label: 'NG0910: Unsafe bindings on an iframe element', - path: 'errors/NG0910', - contentPath: 'reference/errors/NG0910', - }, - { - label: 'NG0912: Component ID generation collision', - path: 'errors/NG0912', - contentPath: 'reference/errors/NG0912', - }, - { - label: 'NG0913: Runtime Performance Warnings', - path: 'errors/NG0913', - contentPath: 'reference/errors/NG0913', - }, - { - label: 'NG0950: Required input is accessed before a value is set.', - path: 'errors/NG0950', - contentPath: 'reference/errors/NG0950', - }, - { - label: 'NG0951: Child query result is required but no value is available.', - path: 'errors/NG0951', - contentPath: 'reference/errors/NG0951', - }, - { - label: 'NG0955: Track expression resulted in duplicated keys for a given collection', - path: 'errors/NG0955', - contentPath: 'reference/errors/NG0955', - }, - { - label: 'NG0956: Tracking expression caused re-creation of the DOM structure', - path: 'errors/NG0956', - contentPath: 'reference/errors/NG0956', - }, - { - label: 'NG1001: Argument Not Literal', - path: 'errors/NG1001', - contentPath: 'reference/errors/NG1001', - }, - { - label: 'NG2003: Missing Token', - path: 'errors/NG2003', - contentPath: 'reference/errors/NG2003', - }, - { - label: 'NG2009: Invalid Shadow DOM selector', - path: 'errors/NG2009', - contentPath: 'reference/errors/NG2009', - }, - { - label: 'NG3003: Import Cycle Detected', - path: 'errors/NG3003', - contentPath: 'reference/errors/NG3003', - }, - { - label: 'NG05000: Hydration with unsupported Zone.js instance.', - path: 'errors/NG05000', - contentPath: 'reference/errors/NG05000', - }, - { - label: 'NG6100: NgModule.id Set to module.id anti-pattern', - path: 'errors/NG6100', - contentPath: 'reference/errors/NG6100', - }, - { - label: 'NG8001: Invalid Element', - path: 'errors/NG8001', - contentPath: 'reference/errors/NG8001', - }, - { - label: 'NG8002: Invalid Attribute', - path: 'errors/NG8002', - contentPath: 'reference/errors/NG8002', - }, - { - label: 'NG8003: Missing Reference Target', - path: 'errors/NG8003', - contentPath: 'reference/errors/NG8003', - }, + ...ERRORS_NAV_DATA, ], }, { @@ -1323,61 +1151,7 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'extended-diagnostics', contentPath: 'reference/extended-diagnostics/overview', }, - { - label: 'NG8101: Invalid Banana-in-Box', - path: 'extended-diagnostics/NG8101', - contentPath: 'reference/extended-diagnostics/NG8101', - }, - { - label: 'NG8102: Nullish coalescing not nullable', - path: 'extended-diagnostics/NG8102', - contentPath: 'reference/extended-diagnostics/NG8102', - }, - { - label: 'NG8103: Missing control flow directive', - path: 'extended-diagnostics/NG8103', - contentPath: 'reference/extended-diagnostics/NG8103', - }, - { - label: 'NG8104: Text attribute not binding', - path: 'extended-diagnostics/NG8104', - contentPath: 'reference/extended-diagnostics/NG8104', - }, - { - label: 'NG8105: Missing `let` keyword in an *ngFor expression', - path: 'extended-diagnostics/NG8105', - contentPath: 'reference/extended-diagnostics/NG8105', - }, - { - label: 'NG8106: Suffix not supported', - path: 'extended-diagnostics/NG8106', - contentPath: 'reference/extended-diagnostics/NG8106', - }, - { - label: 'NG8107: Optional chain not nullable', - path: 'extended-diagnostics/NG8107', - contentPath: 'reference/extended-diagnostics/NG8107', - }, - { - label: 'NG8108: ngSkipHydration should be a static attribute', - path: 'extended-diagnostics/NG8108', - contentPath: 'reference/extended-diagnostics/NG8108', - }, - { - label: 'NG8109: Signals must be invoked in template interpolations', - path: 'extended-diagnostics/NG8109', - contentPath: 'reference/extended-diagnostics/NG8109', - }, - { - label: 'NG8111: Functions must be invoked in event bindings', - path: 'extended-diagnostics/NG8111', - contentPath: 'reference/extended-diagnostics/NG8111', - }, - { - label: 'NG8113: Unused Standalone Imports', - path: 'extended-diagnostics/NG8113', - contentPath: 'reference/extended-diagnostics/NG8113', - }, + ...EXT_DIAGNOSTICS_NAV_DATA, ], }, { @@ -1452,11 +1226,21 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'reference/migrations/signal-inputs', contentPath: 'reference/migrations/signal-inputs', }, + { + label: 'Outputs', + path: 'reference/migrations/outputs', + contentPath: 'reference/migrations/outputs', + }, { label: 'Signal queries', path: 'reference/migrations/signal-queries', contentPath: 'reference/migrations/signal-queries', }, + { + label: 'Clean up unused imports', + path: 'reference/migrations/cleanup-unused-imports', + contentPath: 'reference/migrations/cleanup-unused-imports', + }, ], }, ]; diff --git a/adev-ja/src/content/cli/index.md b/adev-ja/src/content/cli/index.md index 97c07112f..76cc1778f 100644 --- a/adev-ja/src/content/cli/index.md +++ b/adev-ja/src/content/cli/index.md @@ -42,7 +42,7 @@ ng serve In your browser, open http://localhost:4200/ to see the new application run. When you use the [ng serve](cli/serve) command to build an application and serve it locally, the server automatically rebuilds the application and reloads the page when you change any of the source files. -
+
When you run `ng new my-first-project` a new folder, named `my-first-project`, will be created in the current working directory. Since you want to be able to create files inside that folder, make sure you have sufficient rights in the current working directory before running the command. diff --git a/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md b/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md index cfe278e81..2007e832d 100644 --- a/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md +++ b/adev-ja/src/content/ecosystem/rxjs-interop/output-interop.md @@ -1,6 +1,4 @@ -# 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. +# RxJS interop with component and directive outputs Tip: This guide assumes you're familiar with [component and directive outputs](guide/components/outputs). diff --git a/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md b/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md index 410507043..69c3533ba 100644 --- a/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md +++ b/adev-ja/src/content/ecosystem/rxjs-interop/signals-interop.md @@ -69,6 +69,7 @@ Use the `toObservable` utility to create an `Observable` which tracks the value ```ts import { Component, signal } from '@angular/core'; +import { toObservable } from '@angular/core/rxjs-interop'; @Component(...) export class SearchResults { diff --git a/adev-ja/src/content/guide/animations/complex-sequences.md b/adev-ja/src/content/guide/animations/complex-sequences.md index 34d75734c..c8cff5529 100644 --- a/adev-ja/src/content/guide/animations/complex-sequences.md +++ b/adev-ja/src/content/guide/animations/complex-sequences.md @@ -115,8 +115,7 @@ This is because it will lose track of which element is which, resulting in broke The only way to help Angular keep track of such elements is by assigning a `TrackByFunction` to the `NgForOf` directive. This makes sure that Angular always knows which element is which, thus allowing it to apply the correct animations to the correct elements all the time. -IMPORTANT: -If you need to animate the items of an `*ngFor` list and there is a possibility that the order of such items will change during runtime, always use a `TrackByFunction`. +IMPORTANT: If you need to animate the items of an `*ngFor` list and there is a possibility that the order of such items will change during runtime, always use a `TrackByFunction`. ## Animations and Component View Encapsulation 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 5aa2f664d..e62580997 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 @@ -70,7 +70,7 @@ import {ProfilePhoto} from './profile-photo'; export class UserProfile { } ``` -By default, Angular components are *standalone*, meaning that you can directly add them to the `imports` array of other components. Components created with an earlier version of Angular may instead specify `standalone: false` in their `@Component` decorator. For these components, you instead import the `NgMdoule` in which the component is defined. See the full [`NgModule` guide](guide/ngmodules) for details. +By default, Angular components are *standalone*, meaning that you can directly add them to the `imports` array of other components. Components created with an earlier version of Angular may instead specify `standalone: false` in their `@Component` decorator. For these components, you instead import the `NgModule` in which the component is defined. See the full [`NgModule` guide](guide/ngmodules) for details. Important: In Angular versions before 19.0.0, the `standalone` option defaults to `false`. diff --git a/adev-ja/src/content/guide/components/inputs.en.md b/adev-ja/src/content/guide/components/inputs.en.md index 2ca91966c..2716253cd 100644 --- a/adev-ja/src/content/guide/components/inputs.en.md +++ b/adev-ja/src/content/guide/components/inputs.en.md @@ -232,7 +232,7 @@ export class MediaControls { } ``` -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. +In the example above, the `CustomSlider` can write values into its `value` model input, which then propagates those values back to the `volume` property in `MediaControls`. This binding keeps that values of `value` and `volume` in sync. ### Implicit `change` events diff --git a/adev-ja/src/content/guide/components/inputs.md b/adev-ja/src/content/guide/components/inputs.md index ba4d5ca9c..90be1a219 100644 --- a/adev-ja/src/content/guide/components/inputs.md +++ b/adev-ja/src/content/guide/components/inputs.md @@ -232,7 +232,7 @@ export class MediaControls { } ``` -上記の例では、`CustomSlider`は`checked`モデル入力に値を書き込むことができ、それによって`UserProfile`の`isAdmin`プロパティに値が伝播します。このバインディングにより、`checked`と`isAdmin`の値が同期します。 +上記の例では、`CustomSlider`は`value`モデル入力に値を書き込むことができ、それによって`MediaControls`の`volume`プロパティに値が伝播します。このバインディングにより、`value`と`volume`の値が同期します。 ### 暗黙的な`change`イベント @@ -366,7 +366,7 @@ export class CustomSlider { private internalValue = 0; } -可能な場合は、**ゲッターとセッターの代わりに入力変換を使用することをお勧めします。** +可能な場合は、**ゲッターとセッターの代わりに、入力変換を使用することをお勧めします。** 複雑なゲッターとセッター、またはコストの高いゲッターとセッターは避けてください。Angularは入力のセッターを複数回呼び出す可能性があり、セッターがDOM操作などのコストの高い処理を実行する場合、アプリケーションのパフォーマンスに悪影響を与える可能性があります。 diff --git a/adev-ja/src/content/guide/components/lifecycle.en.md b/adev-ja/src/content/guide/components/lifecycle.en.md index e95fc7b91..c2285a425 100644 --- a/adev-ja/src/content/guide/components/lifecycle.en.md +++ b/adev-ja/src/content/guide/components/lifecycle.en.md @@ -261,7 +261,7 @@ export class UserProfile { // Use the `Write` phase to write to a geometric property. write: () => { const padding = computePadding(); - const changed = padding !== prevPadding; + const changed = padding !== this.prevPadding; if (changed) { nativeElement.style.padding = padding; } diff --git a/adev-ja/src/content/guide/components/lifecycle.md b/adev-ja/src/content/guide/components/lifecycle.md index b3d452e5e..d51e5da5c 100644 --- a/adev-ja/src/content/guide/components/lifecycle.md +++ b/adev-ja/src/content/guide/components/lifecycle.md @@ -261,7 +261,7 @@ export class UserProfile { // `Write` フェーズを使用して、ジオメトリのプロパティに書き込みます。 write: () => { const padding = computePadding(); - const changed = padding !== prevPadding; + const changed = padding !== this.prevPadding; if (changed) { nativeElement.style.padding = padding; } diff --git a/adev-ja/src/content/guide/components/queries.en.md b/adev-ja/src/content/guide/components/queries.en.md index b1df7f992..d3a5c8eaf 100644 --- a/adev-ja/src/content/guide/components/queries.en.md +++ b/adev-ja/src/content/guide/components/queries.en.md @@ -156,7 +156,7 @@ export class CustomCard { } ``` -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. +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 automatically include `undefined` in the signal's value type. ## Query locators 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 ce9aeb79a..ea21ebd14 100644 --- a/adev-ja/src/content/guide/di/dependency-injection.en.md +++ b/adev-ja/src/content/guide/di/dependency-injection.en.md @@ -127,7 +127,7 @@ serviceC[Service C] serviceD[Service D] end direction TB -componentConstructor["Component\nconstructor(HeroService)"] +componentConstructor["Component
constructor(HeroService)"] heroService-->componentConstructor style componentConstructor text-align: left ``` diff --git a/adev-ja/src/content/guide/di/dependency-injection.md b/adev-ja/src/content/guide/di/dependency-injection.md index 7b3616dd6..b02514dd4 100644 --- a/adev-ja/src/content/guide/di/dependency-injection.md +++ b/adev-ja/src/content/guide/di/dependency-injection.md @@ -127,7 +127,7 @@ serviceC[Service C] serviceD[Service D] end direction TB -componentConstructor["Component\nconstructor(HeroService)"] +componentConstructor["Component
constructor(HeroService)"] heroService-->componentConstructor style componentConstructor text-align: left ``` 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 b3d5da195..af5ea8b3f 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 @@ -94,9 +94,9 @@ The following diagram represents the relationship between the `root` `ModuleInje ```mermaid stateDiagram-v2 - elementInjector: EnvironmentInjector\n(configured by Angular)\nhas special things like DomSanitizer => providedIn 'platform' - rootInjector: root EnvironmentInjector\n(configured by AppConfig)\nhas things for your app => bootstrapApplication(..., AppConfig) - nullInjector: NullInjector\nalways throws an error unless\nyou use @Optional() + elementInjector: EnvironmentInjector
(configured by Angular)
has special things like DomSanitizer => providedIn 'platform' + rootInjector: root EnvironmentInjector
(configured by AppConfig)
has things for your app => bootstrapApplication(..., AppConfig) + nullInjector: NullInjector
always throws an error unless
you use @Optional() direction BT rootInjector --> elementInjector 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 ca2544703..0a24ea817 100644 --- a/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md +++ b/adev-ja/src/content/guide/di/hierarchical-dependency-injection.md @@ -94,9 +94,9 @@ bootstrapApplication(AppComponent, appConfig); ```mermaid stateDiagram-v2 - elementInjector: EnvironmentInjector\n(configured by Angular)\nhas special things like DomSanitizer => providedIn 'platform' - rootInjector: root EnvironmentInjector\n(configured by AppConfig)\nhas things for your app => bootstrapApplication(..., AppConfig) - nullInjector: NullInjector\nalways throws an error unless\nyou use @Optional() + elementInjector: EnvironmentInjector
(configured by Angular)
has special things like DomSanitizer => providedIn 'platform' + rootInjector: root EnvironmentInjector
(configured by AppConfig)
has things for your app => bootstrapApplication(..., AppConfig) + nullInjector: NullInjector
always throws an error unless
you use @Optional() direction BT rootInjector --> elementInjector diff --git a/adev-ja/src/content/guide/directives/overview.en.md b/adev-ja/src/content/guide/directives/overview.en.md index 9c223f485..5e59ce2ce 100644 --- a/adev-ja/src/content/guide/directives/overview.en.md +++ b/adev-ja/src/content/guide/directives/overview.en.md @@ -69,6 +69,8 @@ These steps are not necessary to implement `ngClass`. ## Setting inline styles with `NgStyle` +HELPFUL: To add or remove a _single_ style, use [style bindings](guide/templates/binding#css-class-and-style-property-bindings) rather than `NgStyle`. + ### Import `NgStyle` in the component To use `NgStyle`, add it to the component's `imports` list. diff --git a/adev-ja/src/content/guide/directives/overview.md b/adev-ja/src/content/guide/directives/overview.md index ce7d74e45..4270f469c 100644 --- a/adev-ja/src/content/guide/directives/overview.md +++ b/adev-ja/src/content/guide/directives/overview.md @@ -69,6 +69,8 @@ HELPFUL: _単一の_ クラスを追加または削除するには、`NgClass` ## `NgStyle` を使用してインラインスタイルを設定する +HELPFUL: To add or remove a _single_ style, use [style bindings](guide/templates/binding#css-class-and-style-property-bindings) rather than `NgStyle`. + ### コンポーネントに `NgStyle` をインポートする `NgStyle` を使用するには、コンポーネントの `imports` リストに追加します。 diff --git a/adev-ja/src/content/guide/elements.md b/adev-ja/src/content/guide/elements.md index 373dab820..849c93981 100644 --- a/adev-ja/src/content/guide/elements.md +++ b/adev-ja/src/content/guide/elements.md @@ -157,3 +157,10 @@ document.createElement('my-dialog') //--> NgElement & WithProperties<{co document.querySelector('my-other-element') //--> NgElement & WithProperties<{foo: 'bar'}> (custom element) + +## Limitations + +Care should be taken when destroying and then re-attaching custom elements created with `@angular/elements` due to issues with the [disconnect()](https://github.com/angular/angular/issues/38778) callback. Cases where you may run into this issue are: + +- Rendering a component in an `ng-if` or `ng-repeat` in `AngularJs` +- Manually detaching and re-attaching an element to the DOM diff --git a/adev-ja/src/content/guide/forms/overview.en.md b/adev-ja/src/content/guide/forms/overview.en.md index 60a3ea327..88d64454d 100644 --- a/adev-ja/src/content/guide/forms/overview.en.md +++ b/adev-ja/src/content/guide/forms/overview.en.md @@ -110,7 +110,7 @@ The view-to-model diagram shows how data flows when an input field's value is ch ```mermaid flowchart TB U{User} - I("") + I("<input>") CVA(ControlValueAccessor) FC(FormControl) O(Observers) @@ -130,14 +130,14 @@ The model-to-view diagram shows how a programmatic change to the model is propag ```mermaid flowchart TB U{User} - I() + I("<input>") CVA(ControlValueAccessor) FC(FormControl) O(Observers) U-->|"Calls setValue() on the FormControl"|FC FC-->|Notifies the ControlValueAccessor|CVA FC-.->|Fires a 'valueChanges' event to observers|O - CVA-->|"Updates the value of the "|I + CVA-->|"Updates the value of the <input>"|I ``` ### Data flow in template-driven forms @@ -157,7 +157,7 @@ The view-to-model diagram shows how data flows when an input field's value is ch ```mermaid flowchart TB U{User} - I() + I("<input>") CVA(ControlValueAccessor) FC(FormControl) M(NgModel) @@ -207,7 +207,7 @@ flowchart TB FC2(FormControl) O(Observers) CVA(ControlValueAccessor) - I("") + I("<input>") FC2-.->|Fires a 'valueChanges' event to observers|O O-->|ControlValueAccessor receives valueChanges event|CVA CVA-->|Sets the value in the control|I diff --git a/adev-ja/src/content/guide/forms/overview.md b/adev-ja/src/content/guide/forms/overview.md index f23527f8e..757e438c2 100644 --- a/adev-ja/src/content/guide/forms/overview.md +++ b/adev-ja/src/content/guide/forms/overview.md @@ -110,7 +110,7 @@ IMPORTANT: テンプレート駆動フォームでは、真実の源はテンプ ```mermaid flowchart TB U{User} - I("") + I("<input>") CVA(ControlValueAccessor) FC(FormControl) O(Observers) @@ -130,14 +130,14 @@ flowchart TB ```mermaid flowchart TB U{User} - I() + I("<input>") CVA(ControlValueAccessor) FC(FormControl) O(Observers) U-->|"Calls setValue() on the FormControl"|FC FC-->|Notifies the ControlValueAccessor|CVA FC-.->|Fires a 'valueChanges' event to observers|O - CVA-->|"Updates the value of the "|I + CVA-->|"Updates the value of the <input>"|I ``` ### テンプレート駆動フォームのデータフロー @@ -157,7 +157,7 @@ flowchart TB ```mermaid flowchart TB U{User} - I() + I("<input>") CVA(ControlValueAccessor) FC(FormControl) M(NgModel) @@ -207,7 +207,7 @@ flowchart TB FC2(FormControl) O(Observers) CVA(ControlValueAccessor) - I("") + I("<input>") FC2-.->|Fires a 'valueChanges' event to observers|O O-->|ControlValueAccessor receives valueChanges event|CVA CVA-->|Sets the value in the control|I 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 c29bb8ba4..8911830e0 100644 --- a/adev-ja/src/content/guide/http/making-requests.en.md +++ b/adev-ja/src/content/guide/http/making-requests.en.md @@ -18,9 +18,9 @@ http.get('/api/config').subscribe(config => { }); -Note the generic type argument which specifies that the data returned by the server will be of type `Config`. This argument is optional, and if you omit it then the returned data will have type `any`. +Note the generic type argument which specifies that the data returned by the server will be of type `Config`. This argument is optional, and if you omit it then the returned data will have type `Object`. -Tip: If the data has an unknown shape, then a safer alternative to `any` is to use the `unknown` type as the response type. +Tip: When dealing with data of uncertain structure and potential `undefined` or `null` values, consider using the `unknown` type instead of `Object` as the response type. CRITICAL: The generic type of request methods is a type **assertion** about the data returned by the server. `HttpClient` does not verify that the actual return data matches this type. diff --git a/adev-ja/src/content/guide/http/making-requests.md b/adev-ja/src/content/guide/http/making-requests.md index 3e3fbcd16..6494c5e0c 100644 --- a/adev-ja/src/content/guide/http/making-requests.md +++ b/adev-ja/src/content/guide/http/making-requests.md @@ -18,9 +18,9 @@ http.get('/api/config').subscribe(config => { }); -サーバーによって返されるデータが `Config` 型であることを指定するジェネリック型引数に注意してください。この引数は省略可能であり、省略すると、返されるデータは `any` 型になります。 +サーバーによって返されるデータが `Config` 型であることを指定するジェネリック型引数に注意してください。この引数は省略可能であり、省略すると、返されるデータは `Object` 型になります。 -Tip: データの形が不明な場合は、`any` 型よりも安全な代替手段として、`unknown` 型をレスポンス型として使用します。 +Tip: 不確実な構造のデータや `undefined` または `null` の値を扱う場合、レスポンスタイプとして `Object` の代わりに `unknown` 型を使用することを検討してください。 CTIRICAL: リクエストメソッドのジェネリック型は、サーバーによって返されるデータに関する**アサーション**です。`HttpClient` は、実際の戻り値データがこの型と一致することを検証しません。 diff --git a/adev-ja/src/content/guide/hybrid-rendering.en.md b/adev-ja/src/content/guide/hybrid-rendering.en.md index 7206518bc..38ce6643a 100644 --- a/adev-ja/src/content/guide/hybrid-rendering.en.md +++ b/adev-ja/src/content/guide/hybrid-rendering.en.md @@ -263,8 +263,7 @@ export class MyComponent { } ``` -IMPORTANT: The above tokens will be `null` in the following scenarios:

- +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). @@ -272,7 +271,7 @@ IMPORTANT: The above tokens will be `null` in the following scenarios:

## 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). +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/AngularAppEngine). ```typescript // server.ts @@ -302,7 +301,7 @@ import express from 'express'; const app = express(); const angularApp = new AngularNodeAppEngine(); -app.get('*', (req, res, next) => +app.use('*', (req, res, next) => { angularApp .handle(req) .then(response => { @@ -319,4 +318,4 @@ app.get('*', (req, res, 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/hybrid-rendering.md b/adev-ja/src/content/guide/hybrid-rendering.md index b039562e3..2aa150dc3 100644 --- a/adev-ja/src/content/guide/hybrid-rendering.md +++ b/adev-ja/src/content/guide/hybrid-rendering.md @@ -272,7 +272,7 @@ IMPORTANT: 上記のトークンは、次のシナリオでは`null`になりま ## Node.js以外のサーバーの設定 -`@angular/ssr`は、Node.js以外のプラットフォームでAngularアプリケーションをサーバーサイドレンダリングするための重要なAPIを提供します。Web APIの標準的な[`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)と[`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)オブジェクトを活用することで、さまざまなサーバー環境にAngular SSRを統合できます。詳細情報と例については、[`@angular/ssr` APIリファレンス](api/ssr/node/AngularAppEngine)を参照してください。 +`@angular/ssr`は、Node.js以外のプラットフォームでAngularアプリケーションをサーバーサイドレンダリングするための重要なAPIを提供します。Web APIの標準的な[`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)と[`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)オブジェクトを活用することで、さまざまなサーバー環境にAngular SSRを統合できます。詳細情報と例については、[`@angular/ssr` APIリファレンス](api/ssr/AngularAppEngine)を参照してください。 ```typescript // server.ts @@ -302,7 +302,7 @@ import express from 'express'; const app = express(); const angularApp = new AngularNodeAppEngine(); -app.get('*', (req, res, next) => +app.use('*', (req, res, next) => { angularApp .handle(req) .then(response => { diff --git a/adev-ja/src/content/guide/hydration.en.md b/adev-ja/src/content/guide/hydration.en.md index b5baa63d9..6952337dd 100644 --- a/adev-ja/src/content/guide/hydration.en.md +++ b/adev-ja/src/content/guide/hydration.en.md @@ -99,11 +99,12 @@ As an example, here are some of the most common cases of this issue. - `` without a `` - `` element inside tables, modern browsers automatically create a `` element in tables that do not declare one. Because of this inconsistency, always explicitly declare a `` element in tables to avoid hydration errors. + ### Preserve Whitespaces Configuration When using the hydration feature, we recommend using the default setting of `false` for `preserveWhitespaces`. If this setting is not in your tsconfig, the value will be `false` and no changes are required. If you choose to enable preserving whitespaces by adding `preserveWhitespaces: true` to your tsconfig, it is possible you may encounter issues with hydration. This is not yet a fully supported configuration. @@ -150,6 +151,10 @@ The `ngSkipHydration` attribute can only be used on component host nodes. Angula Keep in mind that adding the `ngSkipHydration` attribute to your root application component would effectively disable hydration for your entire application. Be careful and thoughtful about using this attribute. It is intended as a last resort workaround. Components that break hydration should be considered bugs that need to be fixed. +## Hydration Timing and Application Stability + +Application stability is an important part of the hydration process. Hydration and any post-hydration processes only occur once the application has reported stability. There are a number of ways that stability can be delayed. Examples include setting timeouts and intervals, unresolved promises, and pending microtasks. In those cases, you may encounter the [Application remains unstable](errors/NG0506) error, which indicates that your app has not yet reached the stable state after 10 seconds. If you're finding that your application is not hydrating right away, take a look at what is impacting application stability and refactor to avoid causing these delays. + ## I18N HELPFUL: Support for internationalization with hydration is currently in [developer preview](/reference/releases#developer-preview). By default, Angular will skip hydration for components that use i18n blocks, effectively re-rendering those components from scratch. @@ -169,10 +174,17 @@ bootstrapApplication(AppComponent, { }); ``` +## Consistent rendering across server-side and client-side +Avoid introducing `@if` blocks and other conditionals that display different content when server-side rendering than client-side rendering, such as using an `@if` block with Angular's `isPlatformBrowser` function. These rendering differences cause layout shifts, negatively impacting end-user experience and core web vitals. + ## Third Party Libraries with DOM Manipulation There are a number of third party libraries that depend on DOM manipulation to be able to render. D3 charts is a prime example. These libraries worked without hydration, but they may cause DOM mismatch errors when hydration is enabled. For now, if you encounter DOM mismatch errors using one of these libraries, you can add the `ngSkipHydration` attribute to the component that renders using that library. +## Third Party Scripts with DOM Manipulation + +Many third party scripts, such as ad trackers and analytics, modify the DOM before hydration can occur. These scripts may cause hydration errors because the page no longer matches the structure expected by Angular. Prefer deferring this type of script until after hydration whenever possible. Consider using [`AfterNextRender`](api/core/afterNextRender) to delay the script until post-hydration processes have occured. + ## Incremental Hydration Incremental hydration is an advanced form of hydration that allows for more granular control over when hydration happens. See the [incremental hydration guide](guide/incremental-hydration) for more information. diff --git a/adev-ja/src/content/guide/hydration.md b/adev-ja/src/content/guide/hydration.md index a86cb685a..6f8d35085 100644 --- a/adev-ja/src/content/guide/hydration.md +++ b/adev-ja/src/content/guide/hydration.md @@ -2,25 +2,25 @@ ## ハイドレーションとは -ハイドレーションとは、サーバーサイドでレンダリングされたアプリケーションをクライアントで復元するプロセスです。これには、サーバーでレンダリングされたDOM構造の再利用、アプリケーション状態の永続化、サーバーで既に取得されたアプリケーションデータの転送、その他のプロセスが含まれます。 +ハイドレーションとは、サーバーサイドでレンダリングされたアプリケーションをクライアントサイドで復元するプロセスです。これには、サーバーでレンダリングされたDOM構造の再利用、アプリケーション状態の永続化、サーバーですでに取得されたアプリケーションデータの転送などが含まれます。 ## なぜハイドレーションが重要なのか -ハイドレーションは、DOMノードの再作成に余分な作業を避けることで、アプリケーションのパフォーマンスを向上させます。代わりにAngularは、実行時に既存のDOM要素をアプリケーションの構造に一致させ、可能な限りDOMノードを再利用しようとします。これにより、[Core Web Vitals (CWV)](https://web.dev/learn-core-web-vitals/)統計を使用して測定できるパフォーマンスの向上をもたらします。たとえば、First Input Delay ([FID](https://web.dev/fid/))とLargest Contentful Paint ([LCP](https://web.dev/lcp/))を削減したり、Cumulative Layout Shift ([CLS](https://web.dev/cls/))を減らしたりできます。これらの数値を改善することで、SEOのパフォーマンスにも影響します。 +ハイドレーションは、DOMノードの再作成に伴う余計な作業を避けることで、アプリケーションのパフォーマンスを向上させます。Angularは、実行時に既存のDOM要素をアプリケーションの構造に一致させ、可能な限りDOMノードを再利用しようとします。これにより、[Core Web Vitals (CWV)](https://web.dev/learn-core-web-vitals/)統計を使用して測定できるパフォーマンスの向上をもたらします。例えば、First Input Delay ([FID](https://web.dev/fid/))やLargest Contentful Paint ([LCP](https://web.dev/lcp/))を削減したり、Cumulative Layout Shift ([CLS](https://web.dev/cls/))を減らしたりできます。これらの数値を改善することで、SEOのパフォーマンスにも影響します。 -ハイドレーションを有効にしないと、サーバーサイドでレンダリングされたAngularアプリケーションはアプリケーションのDOMを破壊して再レンダリングするため、UIのちらつきが目に見える可能性があります。この再レンダリングは、[LCP](https://web.dev/lcp/)などの[Core Web Vitals](https://web.dev/learn-core-web-vitals/)に悪影響を与え、レイアウトのずれを引き起こす可能性があります。ハイドレーションを有効にすると、既存のDOMを再利用できるため、ちらつきを防ぐことができます。 +ハイドレーションを有効にしないと、サーバーサイドでレンダリングされたAngularアプリケーションはアプリケーションのDOMを破棄して再レンダリングするため、UIのちらつきが目に見える可能性があります。この再レンダリングは、[LCP](https://web.dev/lcp/)などの[Core Web Vitals](https://web.dev/learn-core-web-vitals/)に悪影響を与え、レイアウトのずれを引き起こす可能性があります。ハイドレーションを有効にすると、既存のDOMを再利用できるため、ちらつきを防ぐことができます。 ## Angularでハイドレーションを有効にする方法 -ハイドレーションは、サーバーサイドでレンダリングされた(SSR)アプリケーションでのみ有効にできます。サーバーサイドレンダリングを有効にするには、まず[Angular SSRガイド](guide/ssr)に従ってください。 +ハイドレーションは、サーバーサイドでレンダリングされた(SSR)アプリケーションでのみ有効にできます。サーバーサイドレンダリングを有効にするには、まず[Angular SSRガイド](guide/ssr)を参照してください。 ### Angular CLIを使用する -Angular CLIを使用してSSRを有効にした場合(アプリケーションの作成時に有効にしたか、後で`ng add @angular/ssr`を使用して有効にしたかのどちらか)、ハイドレーションを有効にするコードは、すでにアプリケーションに含まれています。 +Angular CLIを使用してSSRを有効にした場合(アプリケーション作成時に有効にしたか、後で`ng add @angular/ssr`を使用して有効にしたかのどちらか)、ハイドレーションを有効にするコードは、すでにアプリケーションに含まれています。 ### 手動で設定する -カスタム設定を使用していて、Angular CLIを使用してSSRを有効にしていない場合は、メインのアプリケーションコンポーネントまたはモジュールにアクセスし`@angular/platform-browser`から`provideClientHydration`をインポートすることにより手動でハイドレーションを有効にできます。その後、そのプロバイダーをアプリケーションのブートストラッププロバイダーリストに追加します。 +カスタム設定を使用していて、Angular CLIを使用してSSRを有効にしていない場合は、メインのアプリケーションコンポーネントまたはモジュールにアクセスし`@angular/platform-browser`から`provideClientHydration`をインポートすることで、手動でハイドレーションを有効にできます。その後、そのプロバイダーをアプリケーションのブートストラッププロバイダーリストに追加します。 ```typescript import { @@ -34,7 +34,7 @@ bootstrapApplication(AppComponent, { }); ``` -あるいは、NgModulesを使用している場合は、`provideClientHydration`をルートアプリケーションモジュールのプロバイダーリストに追加します。 +あるいは、NgModuleを使用している場合は、`provideClientHydration`をルートアプリケーションモジュールのプロバイダーリストに追加します。 ```typescript import {provideClientHydration} from '@angular/platform-browser'; @@ -57,13 +57,13 @@ IMPORTANT: `provideClientHydration()`呼び出しは、**サーバー**上でア HELPFUL: ハイドレーションが完全に機能するためには、直接DOM操作のインスタンスを修正する必要がある場合があります。これは、Angularの構造に切り替えるか、`ngSkipHydration`を使用することで実現できます。詳細については、[制約](#constraints)、[直接DOM操作](#direct-dom-manipulation)、および[特定のコンポーネントのハイドレーションをスキップする方法](#how-to-skip-hydration-for-particular-components)を参照してください。 -アプリケーションを開発モードで実行している間は、ブラウザの開発者ツールを開いてコンソールを表示することで、ハイドレーションが有効になっていることを確認できます。ハイドレーション関連の統計を含むメッセージが表示されます。たとえば、ハイドレーションされたコンポーネントやノードの数などです。Angularは、サードパーティライブラリから来たコンポーネントを含む、ページにレンダリングされたすべてのコンポーネントに基づいて統計を計算します。 +アプリケーションを開発モードで実行している間は、ブラウザの開発者ツールを開いてコンソールを表示することで、ハイドレーションが有効になっていることを確認できます。ハイドレーション関連の統計を含むメッセージが表示されます。例えば、ハイドレーションされたコンポーネントやノードの数などです。Angularは、サードパーティライブラリから来たコンポーネントを含む、ページにレンダリングされたすべてのコンポーネントに基づいて統計を計算します。 [Angular DevToolsブラウザ拡張機能](tools/devtools)を使用して、ページのコンポーネントのハイドレーションステータスを確認できます。Angular DevToolsでは、ページのどの部分がハイドレーションされたかを示すオーバーレイを有効にできます。ハイドレーションのミスマッチエラーが発生した場合は、DevToolsによってエラーの原因となったコンポーネントも強調表示されます。 ## イベントのキャプチャと再生 -アプリケーションがサーバーでレンダリングされると、生成されたHTMLがロードされるとすぐにブラウザに表示されます。ユーザーはページと対話できると仮定する可能性がありますが、イベントリスナーはハイドレーションが完了するまでアタッチされません。v18以降、ハイドレーションの前に発生したすべてのイベントをキャプチャし、ハイドレーションが完了したらそれらのイベントを再生できるイベント再生機能を有効にできます。たとえば、`withEventReplay()`関数を用いて有効にできます。 +アプリケーションがサーバーでレンダリングされると、生成されたHTMLはロードされるとすぐにブラウザに表示されます。ユーザーはページと対話できると想定するかもしれませんが、イベントリスナーはハイドレーションが完了するまでアタッチされません。v18以降、ハイドレーションの前に発生したすべてのイベントをキャプチャし、ハイドレーションが完了したらそれらのイベントを再生できるイベント再生機能を有効にできます。例えば、`withEventReplay()`関数を使用して有効にできます。 ```typescript import {provideClientHydration, withEventReplay} from '@angular/platform-browser'; @@ -77,7 +77,7 @@ bootstrapApplication(App, { ## 制約 {#constraints} -ハイドレーションは、ハイドレーションが有効になっていない場合に存在しない、アプリケーションにいくつかの制約を課します。アプリケーションは、サーバーとクライアントの両方で同じDOM構造を生成する必要があります。ハイドレーションのプロセスは、DOMツリーが両方の場所で同じ構造を持つことを期待します。これには、Angularがサーバーでのレンダリング中に生成する空白やコメントノードも含まれます。これらの空白とノードは、サーバーサイドレンダリングプロセスによって生成されたHTMLに存在する必要があります。 +ハイドレーションは、ハイドレーションが無効な場合に存在しない、アプリケーションにいくつかの制約を課します。アプリケーションは、サーバーとクライアントの両方で同じDOM構造を生成する必要があります。ハイドレーションのプロセスは、DOMツリーが両方の場所で同じ構造を持つことを期待します。これには、Angularがサーバーでのレンダリング中に生成する空白やコメントノードも含まれます。これらの空白とノードは、サーバーサイドレンダリングプロセスによって生成されたHTMLに存在する必要があります。 IMPORTANT: サーバーサイドレンダリング操作によって生成されたHTMLは、**サーバーとクライアントの間で**変更されては**なりません**。 @@ -85,25 +85,26 @@ IMPORTANT: サーバーサイドレンダリング操作によって生成され ### 直接DOM操作 {#direct-dom-manipulation} -ネイティブDOM APIを使用してDOMを操作するか、`innerHTML`または`outerHTML`を使用するコンポーネントがある場合、ハイドレーションプロセスはエラーが発生します。DOM操作が問題となる具体的なケースは、`document`にアクセスしたり、特定の要素をクエリしたり、`appendChild`を使用して追加のノードを挿入したりする場合です。DOMノードをデタッチして別の場所に移動しても、エラーが発生します。 +ネイティブDOM APIを使用してDOMを操作するか、`innerHTML`または`outerHTML`を使用するコンポーネントがある場合、ハイドレーションプロセスでエラーが発生します。DOM操作が問題となる具体的なケースは、`document`にアクセスしたり、特定の要素をクエリしたり、`appendChild`を使用して追加のノードを挿入したりする場合です。DOMノードをデタッチして別の場所に移動しても、エラーが発生します。 -これは、AngularはこれらのDOM変更を認識しておらず、ハイドレーションプロセス中に解決できないためです。Angularは特定の構造を期待していますが、ハイドレーションを試みる際に別の構造に出くわします。このミスマッチは、ハイドレーションの失敗につながり、DOMミスマッチエラーが発生します([下記の](#errors)を参照してください)。 +これは、AngularがこれらのDOM変更を認識しておらず、ハイドレーションプロセス中に解決できないためです。Angularは特定の構造を期待していますが、ハイドレーションを試みる際に別の構造に出くわします。このミスマッチは、ハイドレーションの失敗につながり、DOMミスマッチエラーが発生します([下記の](#errors)を参照してください)。 -この種のDOM操作を避けるために、コンポーネントをリファクタリングするのが最適です。可能な場合は、Angular APIを使用して作業するようにしてください。この動作をリファクタリングできない場合は、リファクタリング可能なソリューションになるまで、`ngSkipHydration`属性([下記の](#how-to-skip-hydration-for-particular-components)で説明)を使用してください。 +この種のDOM操作を避けるため、コンポーネントをリファクタリングするのが最適です。可能な場合は、Angular APIを使用して作業するようにしてください。この動作をリファクタリングできない場合は、リファクタリング可能なソリューションになるまで、`ngSkipHydration`属性([下記の](#how-to-skip-hydration-for-particular-components)で説明)を使用してください。 ### 有効なHTML構造 {#valid-html-structure} コンポーネントテンプレートに有効なHTML構造がない場合、ハイドレーション中にDOMミスマッチエラーが発生する可能性があります。 -たとえば、以下は、この問題の最も一般的なケースです。 +例えば、以下は、この問題の最も一般的なケースです。 - ``なしの`
` - `

`内の`

` 要素を含めることは必須ではありませんが、モダンブラウザは `` 要素を宣言していないテーブルに自動的に `` 要素を作成します。この不一致を避けるために、ハイドレーションエラーを防ぐために常にテーブル内に `` 要素を明示的に宣言してください。 + ### 空白の保持構成 ハイドレーション機能を使用する場合は、`preserveWhitespaces`のデフォルト設定`false`を使用することをお勧めします。この設定が`tsconfig`にない場合、値は`false`となり、変更は必要ありません。`tsconfig`に`preserveWhitespaces: true`を追加して空白の保持を有効にする場合、ハイドレーションに問題が発生する可能性があります。これはまだ完全にサポートされている構成ではありません。 @@ -116,17 +117,17 @@ HELPFUL: この設定が、サーバーの`tsconfig.server.json`とブラウザ ハイドレーションは、Zone.jsからのシグナルに依存しています。アプリケーション内部が安定すると、Angularはサーバーでシリアライゼーションプロセスを開始するかクライアントでハイドレーション後のクリーンアップを実行して、主張されていないままのDOMノードを削除できます。 -カスタムまたは「noop」のZone.js実装を提供すると、「安定」イベントのタイミングが異なり、シリアライゼーションまたはクリーンアップが早すぎるか遅すぎるタイミングでトリガーされる可能性があります。これはまだ完全にサポートされている構成ではなく、カスタムZone.js実装の`onStable`イベントのタイミングを調整する必要があるかもしれません。 +カスタムまたは"noop"のZone.js実装を提供すると、"安定"イベントのタイミングが異なり、シリアライゼーションまたはクリーンアップが早すぎるか遅すぎるタイミングでトリガーされる可能性があります。これはまだ完全にサポートされている構成ではなく、カスタムZone.js実装の`onStable`イベントのタイミングを調整する必要があるかもしれません。 ## エラー {#errors} -ノードのミスマッチから、`ngSkipHydration`が有効なホストノードで使用された場合まで、さまざまなハイドレーション関連のエラーが発生する可能性があります。発生する可能性のある最も一般的なエラーケースは、ネイティブAPIを使用して直接DOM操作したために、ハイドレーションがサーバーでレンダリングされたクライアントの期待されるDOMツリー構造を見つけるか、一致させることができない場合です。この種のエラーが発生する可能性のあるもう1つのケースは、前の[有効なHTML構造](#valid-html-structure)セクションで述べたものです。そのため、テンプレートのHTMLが有効な構造を使用していることを確認してください。そうすれば、そのエラーケースを回避できます。 +ノードのミスマッチから、`ngSkipHydration`が有効なホストノードで使用された場合まで、様々なハイドレーション関連のエラーが発生する可能性があります。最も一般的なエラーケースは、ネイティブAPIを使用して直接DOM操作したため、ハイドレーションがサーバーでレンダリングされたクライアントの期待されるDOMツリー構造を見つけられないか、一致させることができない場合です。この種のエラーが発生する可能性のあるもう1つのケースは、前の[有効なHTML構造](#valid-html-structure)セクションで述べたものです。そのため、テンプレートのHTMLが有効な構造を使用していることを確認してください。そうすれば、そのエラーケースを回避できます。 ハイドレーション関連のエラーに関する完全なリファレンスについては、[エラーリファレンスガイド](/errors)を参照してください。 ## 特定のコンポーネントのハイドレーションをスキップする方法 {#how-to-skip-hydration-for-particular-components} -[直接DOM操作](#direct-dom-manipulation)などの問題により、一部のコンポーネントはハイドレーションを有効にして正常に動作しない場合があります。回避策として、`ngSkipHydration`属性をコンポーネントのタグに追加することで、コンポーネント全体をハイドレーションしないようにできます。 +[直接DOM操作](#direct-dom-manipulation)などの問題により、一部のコンポーネントはハイドレーションを有効にしても正常に動作しない場合があります。回避策として、`ngSkipHydration`属性をコンポーネントのタグに追加することで、コンポーネント全体をハイドレーションしないようにできます。 ```angular-html @@ -142,14 +143,18 @@ HELPFUL: この設定が、サーバーの`tsconfig.server.json`とブラウザ class ExampleComponent {} ``` -`ngSkipHydration`属性は、Angularにコンポーネント全体とその子孫をハイドレーションしないように指示します。この属性を使用すると、コンポーネントはハイドレーションが有効になっていない場合と同じように動作します。つまり、コンポーネントは破棄され、再レンダリングされます。 +`ngSkipHydration`属性は、Angularにコンポーネント全体とその子孫をハイドレーションしないように指示します。この属性を使用すると、コンポーネントはハイドレーションが無効な場合と同じように動作します。つまり、コンポーネントは破棄され、再レンダリングされます。 -HELPFUL: これによりレンダリングの問題は解決されますが、このコンポーネント(とその子孫)については、ハイドレーションの利点は得られません。ハイドレーションを壊すパターン(直接DOM操作など)を避けるために、コンポーネントの実装を調整する必要があります。そうすれば、ハイドレーションをスキップする注釈を削除できます。 +HELPFUL: これによりレンダリングの問題は解決されますが、このコンポーネント(とその子孫)については、ハイドレーションの利点は得られません。ハイドレーションを壊すパターン(直接DOM操作など)を避けるため、コンポーネントの実装を調整する必要があります。そうすれば、ハイドレーションをスキップする注釈を削除できます。 `ngSkipHydration`属性は、コンポーネントのホストノードでのみ使用できます。この属性を他のノードに追加すると、Angularはエラーをスローします。 ルートアプリケーションコンポーネントに`ngSkipHydration`属性を追加すると、事実上、アプリケーション全体でハイドレーションが無効になることに注意してください。この属性を使用する際は注意深く考えてください。これは、最後の手段としての回避策として意図されています。ハイドレーションを壊すコンポーネントは、修正する必要があるバグと見なされるべきです。 +## ハイドレーションのタイミングとアプリケーションの安定性 + +アプリケーションの安定性は、ハイドレーションプロセスの重要な部分です。ハイドレーションとハイドレーション後のプロセスは、アプリケーションが安定状態を報告した後にのみ実行されます。安定性が遅れる原因はいくつかあります。例としては、タイムアウトや間隔の設定、未解決のPromise、保留中のマイクロタスクなどがあります。これらの場合、[アプリケーションは不安定なままです](errors/NG0506)というエラーが発生する可能性があり、これはアプリケーションが10秒後も安定状態に達していないことを示しています。アプリケーションがすぐにハイドレーションされない場合は、アプリケーションの安定性に影響を与える要因を調べ、リファクタリングして遅延を防いでください。 + ## I18N HELPFUL: ハイドレーションを使用した国際化のサポートは現在[開発者プレビュー](/reference/releases#developer-preview)です。デフォルトでは、Angularはi18nブロックを使用するコンポーネントのハイドレーションをスキップし、事実上、それらのコンポーネントを最初から再レンダリングします。 @@ -169,10 +174,17 @@ bootstrapApplication(AppComponent, { }); ``` +## サーバーサイドとクライアントサイドでのレンダリングの一貫性 +`@if`ブロックや、サーバーサイドレンダリング時とクライアントサイドレンダリング時で異なるコンテンツを表示するその他の条件分岐(Angularの`isPlatformBrowser`関数を使用する`@if`ブロックなど)は使用しないでください。これらのレンダリングの違いはレイアウトのずれを引き起こし、ユーザー体験とCore Web Vitalsに悪影響を与えます。 + ## DOM操作を行うサードパーティライブラリ DOM操作に依存してレンダリングを行うサードパーティライブラリがいくつかあります。D3チャートが代表的な例です。これらのライブラリはハイドレーションなしで動作していましたが、ハイドレーションが有効になっているとDOMミスマッチエラーが発生する可能性があります。現時点では、これらのライブラリのいずれかを使用してDOMミスマッチエラーが発生した場合は、そのライブラリを使用してレンダリングを行うコンポーネントに`ngSkipHydration`属性を追加できます。 +## DOM操作を行うサードパーティスクリプト + +多くのサードパーティスクリプト(広告トラッカーや分析ツールなど)は、ハイドレーションが発生する前にDOMを変更します。これらのスクリプトは、ページがAngularが期待する構造と一致しなくなるため、ハイドレーションエラーを引き起こす可能性があります。可能な限り、この種のスクリプトはハイドレーション後まで遅延させることをお勧めします。ハイドレーション後のプロセスが完了するまでスクリプトを遅延させるために、[`AfterNextRender`](api/core/afterNextRender)の使用を検討してください。 + ## インクリメンタルハイドレーション -インクリメンタルハイドレーションはハイドレーションの高度な形態であり、ハイドレーションが起こるタイミングをより細かくコントロールできます。詳しくは[インクリメンタルハイドレーションのガイド](guide/incremental-hydration)を参照してください。 +インクリメンタルハイドレーションは、ハイドレーションの高度な形態であり、ハイドレーションが発生するタイミングをより細かく制御できます。詳しくは[インクリメンタルハイドレーションのガイド](guide/incremental-hydration)を参照してください。 diff --git a/adev-ja/src/content/guide/i18n/deploy.md b/adev-ja/src/content/guide/i18n/deploy.md index 5f9fb37bc..50e8b7293 100644 --- a/adev-ja/src/content/guide/i18n/deploy.md +++ b/adev-ja/src/content/guide/i18n/deploy.md @@ -5,13 +5,11 @@ For example, your French version is located in the `myapp/fr` directory and the The HTML `base` tag with the `href` attribute specifies the base URI, or URL, for relative links. If you set the `"localize"` option in [`angular.json`][GuideWorkspaceConfig] workspace build configuration file to `true` or to an array of locale IDs, the CLI adjusts the base `href` for each version of the application. -To adjust the base `href` for each version of the application, the CLI adds the locale to the configured `"baseHref"`. -Specify the `"baseHref"` for each locale in your [`angular.json`][GuideWorkspaceConfig] workspace build configuration file. -The following example displays `"baseHref"` set to an empty string. +To adjust the base `href` for each version of the application, the CLI adds the locale to the configured `"subPath"`. +Specify the `"subPath"` for each locale in your [`angular.json`][GuideWorkspaceConfig] workspace build configuration file. +The following example displays `"subPath"` set to an empty string. - - -Also, to declare the base `href` at compile time, use the CLI `--baseHref` option with [`ng build`][CliBuild]. + ## Configure a server @@ -21,7 +19,9 @@ If the user has not defined a preferred language, or if the preferred language i To change the language, change your current location to another subdirectory. The change of subdirectory often occurs using a menu implemented in the application. -HELPFUL: For more information on how to deploy apps to a remote server, see [Deployment][GuideDeployment]. +For more information on how to deploy apps to a remote server, see [Deployment][GuideDeployment]. + +IMPORTANT: If you are using [Hybrid rendering](guide/hybrid-rendering) with `outputMode` set to `server`, Angular automatically handles redirection dynamically based on the `Accept-Language` HTTP header. This simplifies deployment by eliminating the need for manual server or configuration adjustments. ### Nginx example diff --git a/adev-ja/src/content/guide/ngmodules/overview.md b/adev-ja/src/content/guide/ngmodules/overview.md index 9a4e61b73..1e901e778 100644 --- a/adev-ja/src/content/guide/ngmodules/overview.md +++ b/adev-ja/src/content/guide/ngmodules/overview.md @@ -107,7 +107,7 @@ export class CustomMenuModule { } ## `NgModule` providers -Tip: See the [Dependency Injection guide](guides/di) for information on dependency injection and providers. +Tip: See the [Dependency Injection guide](guide/di) for information on dependency injection and providers. An `NgModule` can specify `providers` for injected dependencies. These providers are available to: * Any standalone component, directive, or pipe that imports the NgModule, and @@ -152,7 +152,7 @@ boorstrapApplication(MyApplicationRoot, { }); ``` -Similarly, some NgModules may before a static `forChild` that indicates the providers are intended to be added to components within your application hierarchy. +Similarly, some NgModules may define a static `forChild` that indicates the providers are intended to be added to components within your application hierarchy. ```typescript @Component({ @@ -178,7 +178,7 @@ import {platformBrowser} from '@angular/platform-browser'; @NgModule({ bootstrap: [MyApplication], }) -export class MyApplciationModule { } +export class MyApplicationModule { } platformBrowser().bootstrapModule(MyApplicationModule); ``` diff --git a/adev-ja/src/content/guide/prerendering.en.md b/adev-ja/src/content/guide/prerendering.en.md index e9b14c1e5..2e7ed15d9 100644 --- a/adev-ja/src/content/guide/prerendering.en.md +++ b/adev-ja/src/content/guide/prerendering.en.md @@ -16,7 +16,7 @@ ng add @angular/ssr -
+
To create an application with prerendering capabilities from the beginning use the [`ng new --ssr`](tools/cli/setup-local) command. diff --git a/adev-ja/src/content/guide/prerendering.md b/adev-ja/src/content/guide/prerendering.md index cb77697a6..e34264490 100644 --- a/adev-ja/src/content/guide/prerendering.md +++ b/adev-ja/src/content/guide/prerendering.md @@ -16,7 +16,7 @@ ng add @angular/ssr -
+
最初からプリレンダリング機能を持つアプリケーションを作成するには、[`ng new --ssr`](tools/cli/setup-local) コマンドを使用します。 diff --git a/adev-ja/src/content/guide/routing/common-router-tasks.en.md b/adev-ja/src/content/guide/routing/common-router-tasks.en.md index a0b2b1f26..57f39c217 100644 --- a/adev-ja/src/content/guide/routing/common-router-tasks.en.md +++ b/adev-ja/src/content/guide/routing/common-router-tasks.en.md @@ -102,7 +102,7 @@ Now that you have defined your routes, add them to your application. First, add - + ``` You also need to add the `RouterLink`, `RouterLinkActive`, and `RouterOutlet` to the `imports` array of `AppComponent`. @@ -110,7 +110,7 @@ You also need to add the `RouterLink`, `RouterLinkActive`, and `RouterOutlet` to ```ts @Component({ selector: 'app-root', - imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive], + imports: [RouterOutlet, RouterLink, RouterLinkActive], templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) @@ -269,7 +269,7 @@ Here, `FirstComponent` has its own ` - + ``` A child route is like any other route, in that it needs both a `path` and a `component`. @@ -328,7 +328,7 @@ HELPFUL: The `title` property follows the same rules as static route `data` and You can also provide a custom title strategy by extending the `TitleStrategy`. ```ts -@Injectable({providedIn: 'root'}) +@Injectable({ providedIn: 'root' }) export class TemplatePageTitleStrategy extends TitleStrategy { constructor(private readonly title: Title) { super(); @@ -345,7 +345,7 @@ export class TemplatePageTitleStrategy extends TitleStrategy { export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), - {provide: TitleStrategy, useClass: TemplatePageTitleStrategy}, + { provide: TitleStrategy, useClass: TemplatePageTitleStrategy }, ] }; ``` @@ -365,7 +365,7 @@ Rather than writing out the whole path to get to `SecondComponent`, use the `../
  • Relative Route to second component
  • - + ``` In addition to `../`, use `./` or no leading slash to specify the current level. @@ -394,12 +394,12 @@ Sometimes, a feature of your application requires accessing a part of a route, s In this example, the route contains an `id` parameter we can use to target a specific hero page. ```ts -import {ApplicationConfig} from "@angular/core"; -import {Routes} from '@angular/router'; -import {HeroListComponent} from './hero-list.component'; +import { ApplicationConfig } from "@angular/core"; +import { Routes } from '@angular/router'; +import { HeroListComponent } from './hero-list.component'; export const routes: Routes = [ - {path: 'hero/:id', component: HeroDetailComponent} + { path: 'hero/:id', component: HeroDetailComponent } ]; export const appConfig: ApplicationConfig = { @@ -410,15 +410,15 @@ export const appConfig: ApplicationConfig = { First, import the following members in the component you want to navigate from. ```ts +import { inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { Observable, switchMap } from 'rxjs'; ``` Next inject the activated route service: ```ts -constructor(private route: ActivatedRoute) {} +private readonly route = inject(ActivatedRoute); ``` Configure the class so that you have an observable, `heroes$`, a `selectedId` to hold the `id` number of the hero, and the heroes in the `ngOnInit()`, add the following code to get the `id` of the selected hero. @@ -449,11 +449,10 @@ import { Observable } from 'rxjs'; Inject `ActivatedRoute` and `Router` in the constructor of the component class so they are available to this component: ```ts -hero$: Observable; +private readonly route = inject(ActivatedRoute); +private readonly router = inject(Router); -constructor( - private route: ActivatedRoute, - private router: Router ) {} +hero$: Observable; ngOnInit() { const heroId = this.route.snapshot.paramMap.get('id'); @@ -516,10 +515,11 @@ The following example uses `canActivateFn` to guard the route. ```ts export const yourGuardFunction: CanActivateFn = ( - next: ActivatedRouteSnapshot, - state: RouterStateSnapshot) => { - // your logic goes here - } + next: ActivatedRouteSnapshot, + state: RouterStateSnapshot +) => { + // your logic goes here +} ``` In your routing module, use the appropriate property in your `routes` configuration. @@ -600,7 +600,7 @@ You could also redefine the `AppComponent` template with Crisis Center routes ex Dragon Crisis Shark Crisis - + ` }) export class AppComponent {} diff --git a/adev-ja/src/content/guide/routing/common-router-tasks.md b/adev-ja/src/content/guide/routing/common-router-tasks.md index 0ab69b3af..23efba236 100644 --- a/adev-ja/src/content/guide/routing/common-router-tasks.md +++ b/adev-ja/src/content/guide/routing/common-router-tasks.md @@ -102,7 +102,7 @@ const routes: Routes = [ - + ``` `AppComponent` の `imports` 配列に `RouterLink`、`RouterLinkActive`、`RouterOutlet` を追加する必要もあります。 @@ -110,7 +110,7 @@ const routes: Routes = [ ```ts @Component({ selector: 'app-root', - imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive], + imports: [RouterOutlet, RouterLink, RouterLinkActive], templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) @@ -269,7 +269,7 @@ const routes: Routes = [ - + ``` 子ルートは、`path` と `component` の両方を持つ必要があるという点で、他のルートと同じです。 @@ -328,7 +328,7 @@ HELPFUL: `title` プロパティは、静的なルート `data` や、`ResolveFn `TitleStrategy` を拡張して、カスタムタイトル戦略を提供できます。 ```ts -@Injectable({providedIn: 'root'}) +@Injectable({ providedIn: 'root' }) export class TemplatePageTitleStrategy extends TitleStrategy { constructor(private readonly title: Title) { super(); @@ -345,7 +345,7 @@ export class TemplatePageTitleStrategy extends TitleStrategy { export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), - {provide: TitleStrategy, useClass: TemplatePageTitleStrategy}, + { provide: TitleStrategy, useClass: TemplatePageTitleStrategy }, ] }; ``` @@ -365,7 +365,7 @@ export const appConfig: ApplicationConfig = {
  • Relative Route to second component
  • - + ``` `../` に加えて、`./` または先頭にスラッシュがないものを、現在のレベルを指定するために使用します。 @@ -394,12 +394,12 @@ goToItems() { この例では、ルートに `id` パラメータが含まれており、特定のヒーローページをターゲットにできます。 ```ts -import {ApplicationConfig} from "@angular/core"; -import {Routes} from '@angular/router'; -import {HeroListComponent} from './hero-list.component'; +import { ApplicationConfig } from "@angular/core"; +import { Routes } from '@angular/router'; +import { HeroListComponent } from './hero-list.component'; export const routes: Routes = [ - {path: 'hero/:id', component: HeroDetailComponent} + { path: 'hero/:id', component: HeroDetailComponent } ]; export const appConfig: ApplicationConfig = { @@ -410,15 +410,15 @@ export const appConfig: ApplicationConfig = { まず、ナビゲート元のコンポーネントで、次のメンバーをインポートします。 ```ts +import { inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { Observable, switchMap } from 'rxjs'; ``` 次に、アクティブなルートサービスを注入します。 ```ts -constructor(private route: ActivatedRoute) {} +private readonly route = inject(ActivatedRoute); ``` クラスを構成して、`heroes$` というObservable、ヒーローの `id` 番号を保持する `selectedId`、および `ngOnInit()` 内のヒーローを取得できるようにします。次のコードを追加して、選択したヒーローの `id` を取得します。 @@ -449,11 +449,10 @@ import { Observable } from 'rxjs'; コンポーネントクラスのコンストラクターに `ActivatedRoute` と `Router` を注入して、このコンポーネントで使用できるようにします。 ```ts -hero$: Observable; +private readonly route = inject(ActivatedRoute); +private readonly router = inject(Router); -constructor( - private route: ActivatedRoute, - private router: Router ) {} +hero$: Observable; ngOnInit() { const heroId = this.route.snapshot.paramMap.get('id'); @@ -516,10 +515,11 @@ ng generate guard your-guard ```ts export const yourGuardFunction: CanActivateFn = ( - next: ActivatedRouteSnapshot, - state: RouterStateSnapshot) => { - // your logic goes here - } + next: ActivatedRouteSnapshot, + state: RouterStateSnapshot +) => { + // your logic goes here +} ``` ルーティングモジュールで、`routes` 構成の適切なプロパティを使用します。 @@ -600,7 +600,7 @@ export const yourGuardFunction: CanActivateFn = ( Dragon Crisis Shark Crisis - + ` }) export class AppComponent {} diff --git a/adev-ja/src/content/guide/signals/linked-signal.en.md b/adev-ja/src/content/guide/signals/linked-signal.en.md index 97a806747..595d07d04 100644 --- a/adev-ja/src/content/guide/signals/linked-signal.en.md +++ b/adev-ja/src/content/guide/signals/linked-signal.en.md @@ -1,4 +1,4 @@ -# `linkedSignal` +# Dependent state with `linkedSignal` IMPORTANT: `linkedSignal` is [developer preview](reference/releases#developer-preview). It's ready for you to try, but it might change before it is stable. @@ -16,7 +16,7 @@ export class ShippingMethodPicker { this.selectedOption.set(this.shippingOptions()[newOptionIndex]); } } -``` +``` In this example, the `selectedOption` defaults to the first option, but changes if the user selects another option. But `shippingOptions` is a signal— its value may change! If `shippingOptions` changes, `selectedOption` may contain a value that is no longer a valid option. @@ -45,7 +45,7 @@ const shippingOptions = signal(['Ground', 'Air', 'Sea']); const selectedOption = linkedSignal(() => shippingOptions()[0]); console.log(selectedOption()); // 'Ground' -selectedOption.set(shippingOptions[2]); +selectedOption.set(shippingOptions()[2]); console.log(selectedOption()); // 'Sea' shippingOptions.set(['Email', 'Will Call', 'Postal service']); @@ -62,15 +62,15 @@ In the example above, `selectedOption` always updates back to the first option w @Component({/* ... */}) export class ShippingMethodPicker { shippingOptions: Signal = getShippingOptions(); - - selectedOption = linkedSignal({ + + selectedOption = linkedSignal({ // `selectedOption` is set to the `computation` result whenever this `source` changes. - source: shippingOptions, + source: this.shippingOptions, computation: (newOptions, previous) => { // If the newOptions contain the previously selected option, preserve that selection. // Otherwise, default to the first option. - return newOptions.find(opt => opt.id === previous?.value) ?? newOptions[0]; - } + return newOptions.find(opt => opt.id === previous?.value?.id) ?? newOptions[0]; + } }); changeShipping(newOptionIndex: number) { @@ -87,23 +87,20 @@ The `computation` is a function that receives the new value of `source` and a `p ## Custom equality comparison -`linkedSignal` updates to the result of the computation every time its linked state changes. By default, Angular uses referential equality to determine if the linked state has changed. You can alternatively provide a custom equality function. +`linkedSignal`, as any other signal, can be configured with a custom equality function. This function is used by downstream dependencies to determine if that value of the `linkedSignal` (result of a computation) changed: ```typescript -const activeUser = signal({id: 123, name: 'Morgan'}); -const email = linkedSignal(() => `${activeUser().name}@example.com`, { +const activeUser = signal({id: 123, name: 'Morgan', isAdmin: true}); + +const activeUserEditCopy = linkedSignal(() => activeUser()), { // Consider the user as the same if it's the same `id`. equal: (a, b) => a.id === b.id, }); // Or, if separating `source` and `computation` -const alternateEmail = linkedSignal({ +const activeUserEditCopy = linkedSignal({ source: activeUser, - computation: user => `${user.name}@example.com`, + computation: user => user, equal: (a, b) => a.id === b.id, }); - -// This update to `activeUser` does not cause `email` or `alternateEmail` -// to update because the `id` is the same. -activeUser.set({id: 123, name: 'Morgan', isAdmin: false}); ``` diff --git a/adev-ja/src/content/guide/signals/linked-signal.md b/adev-ja/src/content/guide/signals/linked-signal.md index d87518814..10304749c 100644 --- a/adev-ja/src/content/guide/signals/linked-signal.md +++ b/adev-ja/src/content/guide/signals/linked-signal.md @@ -1,8 +1,8 @@ -# `linkedSignal` +# `linkedSignal`による依存状態 IMPORTANT: `linkedSignal`は[開発者プレビュー](reference/releases#developer-preview)です。試用できますが、安定版になる前に変更される可能性があります。 -`signal`関数は、Angularコードで状態を保持するために使用できます。この状態は、他の状態に依存することがあります。たとえば、ユーザーが注文の配送方法を選択できるコンポーネントを考えてみましょう。 +`signal`関数は、Angularコードで状態を保持するために使用できます。この状態は、他の状態に依存することがあります。例えば、ユーザーが注文の配送方法を選択できるコンポーネントを考えてみましょう。 ```typescript @Component({/* ... */}) @@ -45,7 +45,7 @@ const shippingOptions = signal(['Ground', 'Air', 'Sea']); const selectedOption = linkedSignal(() => shippingOptions()[0]); console.log(selectedOption()); // 'Ground' -selectedOption.set(shippingOptions[2]); +selectedOption.set(shippingOptions()[2]); console.log(selectedOption()); // 'Sea' shippingOptions.set(['Email', 'Will Call', 'Postal service']); @@ -56,21 +56,21 @@ console.log(selectedOption()); // 'Email' 場合によっては、`linkedSignal`の計算で`linkedSignal`の以前の値を考慮する必要があります。 -上記の例では、`shippingOptions`が変更されると、`selectedOption`は常に最初のオプションに戻って更新されます。ただし、選択したオプションがリスト内にまだ存在する場合は、ユーザーの選択を維持したい場合があります。これを実現するには、別々の*ソース*と*算出*を使用して`linkedSignal`を作成できます。 +上記の例では、`shippingOptions`が変更されると、`selectedOption`は常に最初のオプションに戻って更新されます。しかし、選択したオプションがリスト内にまだ存在する場合は、ユーザーの選択を維持したい場合があります。これを実現するには、別々の*ソース*と*算出*を使用して`linkedSignal`を作成できます。 ```typescript @Component({/* ... */}) export class ShippingMethodPicker { shippingOptions: Signal = getShippingOptions(); - - selectedOption = linkedSignal({ - // この`source`が変更されるたびに、`selectedOption`は`computation`の結果に設定されます。 - source: shippingOptions, + + selectedOption = linkedSignal({ + // `selectedOption` is set to the `computation` result whenever this `source` changes. + source: this.shippingOptions, computation: (newOptions, previous) => { - // newOptionsに以前選択したオプションが含まれている場合、その選択を保持します。 - // そうでない場合は、最初のオプションをデフォルトとします。 - return newOptions.find(opt => opt.id === previous?.value) ?? newOptions[0]; - } + // If the newOptions contain the previously selected option, preserve that selection. + // Otherwise, default to the first option. + return newOptions.find(opt => opt.id === previous?.value?.id) ?? newOptions[0]; + } }); changeShipping(newOptionIndex: number) { @@ -79,7 +79,7 @@ export class ShippingMethodPicker { } ``` -`linkedSignal`を作成する際には、算出だけを提供する代わりに、個別の`source`プロパティと`computation`プロパティを持つオブジェクトを渡すことができます。 +`linkedSignal`を作成する際には、算出関数だけを提供する代わりに、個別の`source`プロパティと`computation`プロパティを持つオブジェクトを渡すことができます。 `source`は、`computed`やコンポーネントの`input`などの任意のシグナルにできます。`source`の値が変更されると、`linkedSignal`は提供された`computation`の結果にその値を更新します。 @@ -87,23 +87,20 @@ export class ShippingMethodPicker { ## カスタムの等価比較 -`linkedSignal`は、リンクされた状態が変更されるたびに算出の結果に更新されます。デフォルトでは、Angularは参照の等価性を使用して、リンクされた状態が変更されたかどうかを判断します。代わりに、カスタムの等価関数の指定ができます。 +`linkedSignal`は他のシグナルと同様に、カスタムの等価比較関数を設定できます。この関数は、下流の依存関係によって`linkedSignal`の値(計算結果)が変更されたかどうかを判断するために使用されます。 ```typescript -const activeUser = signal({id: 123, name: 'Morgan'}); -const email = linkedSignal(() => `${activeUser().name}@example.com`, { +const activeUser = signal({id: 123, name: 'Morgan', isAdmin: true}); + +const activeUserEditCopy = linkedSignal(() => activeUser(), { // `id`が同じであれば、ユーザーは同じとみなします。 equal: (a, b) => a.id === b.id, }); -// または、`source`と`computation`を分離する場合 -const alternateEmail = linkedSignal({ +// または、`source`と`computation`を分ける場合 +const activeUserEditCopy = linkedSignal({ source: activeUser, - computation: user => `${user.name}@example.com`, + computation: user => user, equal: (a, b) => a.id === b.id, }); - -// `activeUser`へのこの更新は、`id`が同じであるため、 -// `email`または`alternateEmail`を更新しません。 -activeUser.set({id: 123, name: 'Morgan', isAdmin: false}); ``` diff --git a/adev-ja/src/content/guide/signals/resource.en.md b/adev-ja/src/content/guide/signals/resource.en.md index 3de38a2f1..e06c100c9 100644 --- a/adev-ja/src/content/guide/signals/resource.en.md +++ b/adev-ja/src/content/guide/signals/resource.en.md @@ -4,7 +4,7 @@ IMPORTANT: `resource` is [experimental](reference/releases#experimental). It's r Most signal APIs are synchronous— `signal`, `computed`, `input`, etc. However, applications often need to deal with data that is available asynchronously. A `Resource` gives you a way to incorporate async data into your application's signal-based code. -You can use a `Resource` to perform any kind of async operation, but the most common use-case for `Resource` is fetching data from a server. The following creates a resource to fetch some user data. +You can use a `Resource` to perform any kind of async operation, but the most common use-case for `Resource` is fetching data from a server. The following example creates a resource to fetch some user data. The easiest way to create a `Resource` is the `resource` function. @@ -23,7 +23,7 @@ const userResource = resource({ loader: ({request}) => fetchUser(request), }); -// Created a computed based on the result of the resource's loader function. +// Create a computed signal based on the result of the resource's loader function. const firstName = computed(() => userResource.value().firstName); ``` @@ -47,6 +47,9 @@ The `ResourceLoaderParams` object contains three properties: `request`, `previou | `previous` | An object with a `status` property, containing the previous `ResourceStatus`. | | `abortSignal` | An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal). See [Aborting requests](#aborting-requests) below for details. | + +If the `request` computation returns `undefined`, the loader function does not run and the resource status becomes `Idle`. + ### Aborting requests A resource aborts an outstanding request if the `request` computation changes while the resource is loading. @@ -85,17 +88,13 @@ const userResource = resource({ userResource.reload(); ``` -### `undefined` requests - -A request value of `undefined` prevents the resource from running its loader, and will put the resource into an `Idle` state. - ## Resource status The resource object has several signal properties for reading the status of the asynchronous loader. | Property | Description | | ----------- | --------------------------------------------------------------------------------------------------------------- | -| `value` | The most recent value of the resource, or `undefined` if no value has been recieved. | +| `value` | The most recent value of the resource, or `undefined` if no value has been received. | | `hasValue` | Whether the resource has a value. | | `error` | The most recent error encountered while running the resource's loader, or `undefined` if no error has occurred. | | `isLoading` | Whether the resource loader is currently running. | diff --git a/adev-ja/src/content/guide/signals/resource.md b/adev-ja/src/content/guide/signals/resource.md index fdc104b0f..472f418fc 100644 --- a/adev-ja/src/content/guide/signals/resource.md +++ b/adev-ja/src/content/guide/signals/resource.md @@ -23,7 +23,7 @@ const userResource = resource({ loader: ({request}) => fetchUser(request), }); -// リソースのローダー関数の結果に基づいてcomputedを作成します。 +// リソースのローダー関数の結果に基づいて算出シグナルを作成します。 const firstName = computed(() => userResource.value().firstName); ``` @@ -47,6 +47,9 @@ const firstName = computed(() => userResource.value().firstName); | `previous` | `status`プロパティを含む、前の`ResourceStatus`を持つオブジェクト。 | | `abortSignal` | [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)。詳細は下記の[リクエストの中断](#aborting-requests)を参照してください。 | + +`request`の計算が`undefined`を返す場合、ローダー関数は実行されず、リソースの状態は`Idle`になります。 + ### リクエストの中断 {#aborting-requests} リソースが読み込み中の場合に`request`計算が変更されると、リソースは未処理のリクエストを中断します。 @@ -85,10 +88,6 @@ const userResource = resource({ userResource.reload(); ``` -### `undefined` リクエスト {#undefined-requests} - -`undefined`のリクエスト値は、リソースがローダーを実行するのを防ぎ、リソースを`Idle`状態にします。 - ## リソースの状態 リソースオブジェクトには、非同期ローダーの状態を読み取るためのいくつかのシグナルプロパティがあります。 diff --git a/adev-ja/src/content/guide/ssr.en.md b/adev-ja/src/content/guide/ssr.en.md index c5c9c60a7..d093f0dde 100644 --- a/adev-ja/src/content/guide/ssr.en.md +++ b/adev-ja/src/content/guide/ssr.en.md @@ -41,11 +41,11 @@ To verify that the application is server-side rendered, run it locally with `ng ## Configure server-side rendering -Note: In Angular v17 and later, `server.ts` is no longer used by `ng serve`. The dev server will use `main.server.ts` directly to perfom server side rendering. +Note: In Angular v17 and later, `server.ts` is no longer used by `ng serve`. The dev server will use `main.server.ts` directly to perform server side rendering. The `server.ts` file configures a Node.js Express server and Angular server-side rendering. `CommonEngine` is used to render an Angular application. - + Angular CLI will scaffold an initial server implementation focused on server-side rendering your Angular application. This server can be extended to support other features such as API routes, redirects, static assets, and more. See [Express documentation](https://expressjs.com/) for more details. diff --git a/adev-ja/src/content/guide/ssr.md b/adev-ja/src/content/guide/ssr.md index ed34b075e..ecebdc351 100644 --- a/adev-ja/src/content/guide/ssr.md +++ b/adev-ja/src/content/guide/ssr.md @@ -45,7 +45,7 @@ Note: Angular v17以降 `server.ts` は `ng serve` では使用されていま `server.ts` ファイルは、Node.js ExpressサーバーとAngularサーバーサイドレンダリングを構成します。`CommonEngine` はAngularアプリケーションをレンダリングするために使用されます。 - + Angular CLIは、Angularアプリケーションのサーバーサイドレンダリングに焦点を当てた、初期のサーバー実装をスキャフォールディングします。このサーバーは、APIルート、リダイレクト、静的アセットなど、他の機能をサポートするように拡張できます。詳細については、[Express ドキュメント](https://expressjs.com/) を参照してください。 diff --git a/adev-ja/src/content/guide/templates/control-flow.en.md b/adev-ja/src/content/guide/templates/control-flow.en.md index 861d9247a..735b8a31a 100644 --- a/adev-ja/src/content/guide/templates/control-flow.en.md +++ b/adev-ja/src/content/guide/templates/control-flow.en.md @@ -50,6 +50,8 @@ A typical `@for` loop looks like: } ``` +Angular's `@for` block does not support flow-modifying statements like JavaScript's `continue` or `break`. + ### Why is `track` in `@for` blocks important? The `track` expression allows Angular to maintain a relationship between your data and the DOM nodes on the page. This allows Angular to optimize performance by executing the minimum necessary DOM operations when the data changes. diff --git a/adev-ja/src/content/guide/templates/control-flow.md b/adev-ja/src/content/guide/templates/control-flow.md index 506acc8f3..62240f6cf 100644 --- a/adev-ja/src/content/guide/templates/control-flow.md +++ b/adev-ja/src/content/guide/templates/control-flow.md @@ -50,6 +50,8 @@ Note: これらは、以前は\*ngIf、\*ngFor、\*ngSwitchディレクティブ } ``` +Angularの `@for` ブロックは、JavaScriptの `continue` や `break` のようなフロー変更のステートメントをサポートしていません。 + ### なぜ `@for` ブロックの `track` は重要なのか? `track` 式を使用すると、Angularはデータとページ上のDOMノードの関係を維持できます。 これにより、Angularはデータが変更されたときに、必要なDOM操作を最小限に抑えてパフォーマンスを最適化できます。 diff --git a/adev-ja/src/content/guide/templates/defer.en.md b/adev-ja/src/content/guide/templates/defer.en.md index 354199efd..41dd28e95 100644 --- a/adev-ja/src/content/guide/templates/defer.en.md +++ b/adev-ja/src/content/guide/templates/defer.en.md @@ -10,7 +10,7 @@ To use this feature, you can declaratively wrap a section of your template in a } ``` -The code for any components, directives, and pipes inside of the `@defer` block is split into a separate JavaScript file and loaded only when necessary, after the rest of the template has been rendered. +The code for any components, directives, and pipes inside the `@defer` block is split into a separate JavaScript file and loaded only when necessary, after the rest of the template has been rendered. Deferrable views support a variety of triggers, prefetching options, and sub-blocks for placeholder, loading, and error state management. @@ -20,11 +20,13 @@ Components, directives, pipes, and any component CSS styles can be deferred when In order for the dependencies within a `@defer` block to be deferred, they need to meet two conditions: -1. **They must be standalone.** Non-stadalone dependencies cannot be deferred and are still eagerly loaded, even if they are inside of `@defer` blocks. -1. **They cannot be referenced outside of `@defer` blocks within the same file.** If they are referenced outside of the `@defer` block or referenced within ViewChild queries, the dependencies will be eagerly loaded. +1. **They must be standalone.** Non-standalone dependencies cannot be deferred and are still eagerly loaded, even if they are inside of `@defer` blocks. +1. **They cannot be referenced outside of `@defer` blocks within the same file.** If they are referenced outside the `@defer` block or referenced within ViewChild queries, the dependencies will be eagerly loaded. The _transitive_ dependencies of the components, directives and pipes used in the `@defer` block do not strictly need to be standalone; transitive dependencies can still be declared in an `NgModule` and participate in deferred loading. +Angular's compiler produces a [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) statement for each component, directive, and pipe used in the `@defer` block. The main content of the block renders after all the imports resolve. Angular does not guarantee any particular order for these imports. + ## How to manage different stages of deferred loading `@defer` blocks have several sub blocks to allow you to gracefully handle different stages in the deferred loading process. @@ -189,7 +191,7 @@ By default, the placeholder acts as the interaction element. Placeholders used t } ``` -Alternatively, you can specify a [template reference variable](/guide/templates/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.Z +Alternatively, you can specify a [template reference variable](/guide/templates/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!
    @@ -321,9 +323,9 @@ it('should render a defer block in different states', async () => { ## How does `@defer` work 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). +By default, 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) and triggers are not invoked. On the client, the content of the `@placeholder` is hydrated and triggers are activated. -Triggers are ignored on the server. +To render the main content of `@defer` blocks on the server (both SSR and SSG), you can enable [the Incremental Hydration feature](/guide/incremental-hydration) and configure `hydrate` triggers for the necessary blocks. ## Best practices for deferring views diff --git a/adev-ja/src/content/guide/templates/defer.md b/adev-ja/src/content/guide/templates/defer.md index 46569edef..a50660c08 100644 --- a/adev-ja/src/content/guide/templates/defer.md +++ b/adev-ja/src/content/guide/templates/defer.md @@ -1,8 +1,8 @@ -# `@defer` を用いた遅延読み込み +# `@defer`を用いた遅延読み込み -遅延可能ビュー (別名 `@defer` ブロック) は、ページの初期レンダリングに厳密に必要ないコードの読み込みを遅らせることで、アプリケーションの初期バンドルサイズを削減します。これにより、多くの場合、初期読み込みが高速化され、特にLargest Contentful Paint (LCP) とTime to First Byte (TTFB) に関してCore Web Vitals (CWV) が向上します。 +遅延可能ビュー(別名`@defer`ブロック)は、ページの初期レンダリングに厳密に必要ないコードの読み込みを遅らせることで、アプリケーションの初期バンドルサイズを削減します。これにより、多くの場合、初期読み込みが高速化され、特にLargest Contentful Paint(LCP)とTime to First Byte(TTFB)に関してCore Web Vitals(CWV)が向上します。 -この機能を使用するには、テンプレートのセクションを `@defer` ブロックで宣言的にラップします。 +この機能を使用するには、テンプレートのセクションを`@defer`ブロックで宣言的にラップします。 ```angular-html @defer { @@ -10,7 +10,7 @@ } ``` -`@defer` ブロック内のコンポーネント、ディレクティブ、パイプのコードは、別のJavaScriptファイルに分割され、残りのテンプレートがレンダリングされた後、必要な場合にのみ読み込まれます。 +`@defer`ブロック内のコンポーネント、ディレクティブ、パイプのコードは、別のJavaScriptファイルに分割され、残りのテンプレートがレンダリングされた後、必要な場合にのみ読み込まれます。 遅延可能ビューは、さまざまなトリガーやプリフェッチオプションおよびプレースホルダー、読み込み、エラー状態の管理のためのサブブロックをサポートしています。 @@ -18,22 +18,24 @@ アプリケーションを読み込む際に、コンポーネント、ディレクティブ、パイプ、およびコンポーネントCSSスタイルを遅延させることができます。 -`@defer` ブロック内の依存関係を遅延させるためには、2つの条件を満たす必要があります。 +`@defer`ブロック内の依存関係を遅延させるためには、2つの条件を満たす必要があります。 -1. **スタンドアロンである必要があります。** スタンドアロンではない依存関係は遅延させることができず、`@defer` ブロック内にあっても、依然として先に読み込まれます。 -1. **同じファイル内の `@defer` ブロックの外側では参照できません。** `@defer` ブロックの外側で参照される場合、またはViewChildクエリ内で参照される場合、依存関係は先に読み込まれます。 +1. **スタンドアロンである必要があります。** スタンドアロンでない依存関係は遅延させることができず、`@defer`ブロック内にあっても、依然として先に読み込まれます。 +1. **同じファイル内の`@defer`ブロックの外側では参照できません。** `@defer`ブロックの外側で参照される場合、またはViewChildクエリ内で参照される場合、依存関係は先に読み込まれます。 -`@defer` ブロックで使用されるコンポーネント、ディレクティブ、パイプの _推移的_ 依存関係は、厳密にはスタンドアロンである必要はありません。推移的依存関係は依然として `NgModule` で宣言でき、遅延読み込みに参加できます。 +`@defer`ブロックで使用されるコンポーネント、ディレクティブ、パイプの_推移的_依存関係は、厳密にはスタンドアロンである必要はありません。推移的依存関係は依然として`NgModule`で宣言でき、遅延読み込みに参加できます。 + +Angularのコンパイラは、`@defer`ブロックで使用される各コンポーネント、ディレクティブ、およびパイプに対して[動的インポート](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import)文を生成します。ブロックのメインコンテンツは、すべてのインポートが解決された後にレンダリングされます。Angularは、これらのインポートの特定の順序を保証しません。 ## 遅延読み込みのさまざまなステージを管理する方法 -`@defer` ブロックには、遅延読み込みプロセスにおけるさまざまなステージを適切に処理できるように、いくつかのサブブロックがあります。 +`@defer`ブロックには、遅延読み込みプロセスにおけるさまざまなステージを適切に処理できるように、いくつかのサブブロックがあります。 ### `@defer` -これは、遅延読み込みされるコンテンツのセクションを定義するプライマリブロックです。これは最初はレンダリングされません。遅延コンテンツは、指定された [トリガー](/guide/defer#triggers) が発生するか、`when` 条件が満たされたときに読み込まれてレンダリングされます。 +これは、遅延読み込みされるコンテンツのセクションを定義するプライマリブロックです。これは最初はレンダリングされません。遅延コンテンツは、指定された[トリガー](/guide/defer#triggers)が発生するか、`when`条件が満たされたときに読み込まれてレンダリングされます。 -デフォルトでは、`@defer` ブロックはブラウザの状態が [アイドル](/guide/defer#on-idle) になるとトリガーされます。 +デフォルトでは、`@defer`ブロックはブラウザの状態が[アイドル](/guide/defer#on-idle)になるとトリガーされます。 ```angular-html @defer { @@ -41,11 +43,11 @@ } ``` -### `@placeholder` でプレースホルダーコンテンツを表示する +### `@placeholder`でプレースホルダーコンテンツを表示する -デフォルトでは、`@defer` ブロックはトリガーされる前にコンテンツをレンダリングしません。 +デフォルトでは、`@defer`ブロックはトリガーされる前にコンテンツをレンダリングしません。 -`@placeholder` は、`@defer` ブロックがトリガーされる前に表示するコンテンツを宣言するオプションのブロックです。 +`@placeholder`は、`@defer`ブロックがトリガーされる前に表示するコンテンツを宣言するオプションのブロックです。 ```angular-html @defer { @@ -55,11 +57,11 @@ } ``` -オプションですが、特定のトリガーでは、`@placeholder` または [テンプレート参照変数](/guide/templates/variables#template-reference-variables) のいずれかの存在が必要になる場合があります。詳細については、[トリガー](/guide/defer#triggers) セクションを参照してください。 +オプションですが、特定のトリガーでは、`@placeholder`または[テンプレート参照変数](/guide/templates/variables#template-reference-variables)のいずれかの存在が必要になる場合があります。詳細については、[トリガー](/guide/defer#triggers)セクションを参照してください。 Angularは、読み込みが完了すると、プレースホルダーコンテンツをメインコンテンツに置き換えます。プレースホルダーセクションには、プレーンHTML、コンポーネント、ディレクティブ、パイプなど、あらゆるコンテンツを使用できます。_プレースホルダーブロックの依存関係は先に読み込まれます_。 -`@placeholder` ブロックは、プレースホルダーコンテンツが最初にレンダリングされた後にこのプレースホルダーを表示する `minimum` 時間を指定するオプションのパラメータを受け入れます。 +`@placeholder`ブロックは、プレースホルダーコンテンツが最初にレンダリングされた後にこのプレースホルダーを表示する`minimum`時間を指定するオプションのパラメータを受け入れます。 ```angular-html @defer { @@ -69,11 +71,11 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -この `minimum` パラメータは、ミリ秒 (ms) または秒 (s) の時間増分で指定されます。このパラメータを使用して、遅延された依存関係がすばやく取得された場合にプレースホルダーコンテンツが高速でちらつくのを防ぐことができます。 +この`minimum`パラメータは、ミリ秒(ms)または秒(s)の時間増分で指定されます。このパラメータを使用して、遅延された依存関係がすばやく取得された場合にプレースホルダーコンテンツが高速でちらつくのを防ぐことができます。 -### `@loading` で読み込みコンテンツを表示する +### `@loading`で読み込みコンテンツを表示する -`@loading` ブロックは、遅延された依存関係が読み込まれている間に表示するコンテンツを宣言できるようにするオプションのブロックです。これは、読み込みがトリガーされると `@placeholder` ブロックを置き換えます。 +`@loading`ブロックは、遅延された依存関係が読み込まれている間に表示するコンテンツを宣言できるようにするオプションのブロックです。これは、読み込みがトリガーされると`@placeholder`ブロックを置き換えます。 ```angular-html @defer { @@ -85,9 +87,9 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -その依存関係は先に読み込まれます ( `@placeholder` と同様)。 +その依存関係は先に読み込まれます(`@placeholder`と同様)。 -`@loading` ブロックは、遅延された依存関係がすばやく取得された場合に発生する可能性のあるコンテンツの高速なちらつきを防ぐために、2つのパラメータを受け入れます。 +`@loading`ブロックは、遅延された依存関係がすばやく取得された場合に発生する可能性のあるコンテンツの高速なちらつきを防ぐために、2つのパラメータを受け入れます。 - `minimum` - このプレースホルダーを表示する最小時間 - `after` - 読み込みが開始されてから読み込みテンプレートを表示するまでの待機時間 @@ -100,11 +102,11 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -両方のパラメータは、ミリ秒 (ms) または秒 (s) の時間増分で指定されます。さらに、両方のパラメータのタイマーは、読み込みがトリガーされた直後に開始されます。 +両方のパラメータは、ミリ秒(ms)または秒(s)の時間増分で指定されます。さらに、両方のパラメータのタイマーは、読み込みがトリガーされた直後に開始されます。 -### 遅延読み込みが失敗した場合に `@error` でエラー状態を表示する +### 遅延読み込みが失敗した場合に`@error`でエラー状態を表示する -`@error` ブロックは、遅延読み込みが失敗した場合に表示するオプションのブロックです。`@placeholder` や `@loading` と同様に、`@error` ブロックの依存関係は先に読み込まれます。 +`@error`ブロックは、遅延読み込みが失敗した場合に表示するオプションのブロックです。`@placeholder`や`@loading`と同様に、`@error`ブロックの依存関係は先に読み込まれます。 ```angular-html @defer { @@ -116,17 +118,17 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ ## トリガーを使用した遅延コンテンツ読み込みの制御 -遅延コンテンツがいつ読み込まれて表示されるかを制御する **トリガー** を指定できます。 +遅延コンテンツがいつ読み込まれて表示されるかを制御する**トリガー**を指定できます。 -`@defer` ブロックがトリガーされると、プレースホルダーコンテンツが遅延読み込みされたコンテンツに置き換えられます。 +`@defer`ブロックがトリガーされると、プレースホルダーコンテンツが遅延読み込みされたコンテンツに置き換えられます。 -複数のイベントトリガーを、セミコロン (`;`) で区切って定義でき、OR条件として評価されます。 +複数のイベントトリガーを、セミコロン(`;`)で区切って定義でき、OR条件として評価されます。 -トリガーには、`on` と `when` の2種類があります。 +トリガーには、`on`と`when`の2種類があります。 ### `on` -`on` は、`@defer` ブロックがトリガーされる条件を指定します。 +`on`は、`@defer`ブロックがトリガーされる条件を指定します。 使用可能なトリガーは次のとおりです。 @@ -141,7 +143,7 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ #### `idle` -`idle` トリガーは、ブラウザがrequestIdleCallbackに基づいてアイドル状態に達すると、遅延コンテンツを読み込みます。これは、`@defer` ブロックのデフォルトの動作です。 +`idle`トリガーは、ブラウザがrequestIdleCallbackに基づいてアイドル状態に達すると、遅延コンテンツを読み込みます。これは、`@defer`ブロックのデフォルトの動作です。 ```angular-html @@ -154,9 +156,9 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ #### `viewport` -`viewport` トリガーは、[Intersection Observer API](https://developer.mozilla.org/docs/Web/API/Intersection_Observer_API) を使用して、指定されたコンテンツがビューポートに入ると、遅延コンテンツを読み込みます。観測されるコンテンツは、`@placeholder` コンテンツまたは明示的な要素参照にできます。 +`viewport`トリガーは、[Intersection Observer API](https://developer.mozilla.org/docs/Web/API/Intersection_Observer_API)を使用して、指定されたコンテンツがビューポートに入ると、遅延コンテンツを読み込みます。観測されるコンテンツは、`@placeholder`コンテンツまたは明示的な要素参照にできます。 -デフォルトでは、`@defer` は、プレースホルダーがビューポートに入っているかどうかを観察します。このように使用されるプレースホルダーは、単一のルート要素を持つ必要があります。 +デフォルトでは、`@defer`は、プレースホルダーがビューポートに入っているかどうかを観察します。このように使用されるプレースホルダーは、単一のルート要素を持つ必要があります。 ```angular-html @defer (on viewport) { @@ -166,7 +168,7 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -または、`@defer` ブロックと同じテンプレート内に、ビューポートに入っているかどうかが監視される要素として [テンプレート参照変数](/guide/templates/variables) を指定できます。この変数は、ビューポートトリガーのパラメータとして渡されます。 +または、`@defer`ブロックと同じテンプレート内に、ビューポートに入っているかどうかが監視される要素として[テンプレート参照変数](/guide/templates/variables)を指定できます。この変数は、ビューポートトリガーのパラメータとして渡されます。 ```angular-html
    こんにちは!
    @@ -177,7 +179,7 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ #### `interaction` -`interaction` トリガーは、ユーザーが `click` または `keydown` イベントを通じて指定された要素と対話すると、遅延コンテンツを読み込みます。 +`interaction`トリガーは、ユーザーが`click`または`keydown`イベントを通じて指定された要素と対話すると、遅延コンテンツを読み込みます。 デフォルトでは、プレースホルダーが対話要素として機能します。このように使用されるプレースホルダーは、単一のルート要素を持つ必要があります。 @@ -189,7 +191,7 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -または、`@defer` ブロックと同じテンプレート内に、ビューポートに入っているかどうかが監視される要素として [テンプレート参照変数](/guide/templates/variables) を指定できます。この変数は、ビューポートトリガーのパラメータとして渡されます。Z +または、`@defer`ブロックと同じテンプレート内に、ビューポートに入っているかどうかが監視される要素として[テンプレート参照変数](/guide/templates/variables)を指定できます。この変数は、ビューポートトリガーのパラメータとして渡されます。 ```angular-html
    こんにちは!
    @@ -200,7 +202,7 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ #### `hover` -`hover` トリガーは、マウスが `mouseover` イベントと `focusin` イベントを通じてトリガーされた領域にホバーすると、遅延コンテンツを読み込みます。 +`hover`トリガーは、マウスが`mouseover`イベントと`focusin`イベントを通じてトリガーされた領域にホバーすると、遅延コンテンツを読み込みます。 デフォルトでは、プレースホルダーが対話要素として機能します。このように使用されるプレースホルダーは、単一のルート要素を持つ必要があります。 @@ -212,7 +214,7 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -または、`@defer` ブロックと同じテンプレート内に、ビューポートに入っているかどうかが監視される要素として [テンプレート参照変数](/guide/templates/variables) を指定できます。この変数は、ビューポートトリガーのパラメータとして渡されます。 +または、`@defer`ブロックと同じテンプレート内に、ビューポートに入っているかどうかが監視される要素として[テンプレート参照変数](/guide/templates/variables)を指定できます。この変数は、ビューポートトリガーのパラメータとして渡されます。 ```angular-html
    こんにちは!
    @@ -223,7 +225,7 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ #### `immediate` -`immediate` トリガーは、遅延コンテンツをすぐに読み込みます。これは、遅延ブロックは、他のすべての遅延されていないコンテンツのレンダリングが完了するとすぐに読み込まれることを意味します。 +`immediate`トリガーは、遅延コンテンツをすぐに読み込みます。これは、遅延ブロックは、他のすべての遅延されていないコンテンツのレンダリングが完了するとすぐに読み込まれることを意味します。 ```angular-html @defer (on immediate) { @@ -235,7 +237,7 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ #### `timer` -`timer` トリガーは、指定された期間後に遅延コンテンツを読み込みます。 +`timer`トリガーは、指定された期間後に遅延コンテンツを読み込みます。 ```angular-html @defer (on timer(500ms)) { @@ -245,11 +247,11 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -期間パラメータは、ミリ秒 (`ms`) または秒 (`s`) で指定する必要があります。 +期間パラメータは、ミリ秒(`ms`)または秒(`s`)で指定する必要があります。 ### `when` -`when` トリガーは、カスタムの条件式を受け取り、条件が真になったときに遅延コンテンツを読み込みます。 +`when`トリガーは、カスタムの条件式を受け取り、条件が真になったときに遅延コンテンツを読み込みます。 ```angular-html @defer (when condition) { @@ -259,15 +261,15 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -これは1回限りの操作です。`@defer` ブロックは、真になった後に偽の値に変更された場合、プレースホルダーに復帰しません。 +これは1回限りの操作です。`@defer`ブロックは、真になった後に偽の値に変更された場合、プレースホルダーに復帰しません。 -## `prefetch` でデータをプリフェッチする +## `prefetch`でデータをプリフェッチする -遅延コンテンツが表示される条件を指定することに加えて、**プリフェッチトリガー** をオプションで指定できます。このトリガーを使用すると、`@defer` ブロックに関連付けられたJavaScriptを、遅延コンテンツが表示される前に読み込むことができます。 +遅延コンテンツが表示される条件を指定することに加えて、**プリフェッチトリガー**をオプションで指定できます。このトリガーを使用すると、`@defer`ブロックに関連付けられたJavaScriptを、遅延コンテンツが表示される前に読み込むことができます。 -プリフェッチを使用すると、ユーザーが実際に `@defer` ブロックを表示または対話する前に、ユーザーがすぐに対話する可能性のあるリソースのプリフェッチを開始します。これにより、リソースをより高速に利用できるようにするなど、より高度な動作が可能になります。 +プリフェッチを使用すると、ユーザーが実際に`@defer`ブロックを表示または対話する前に、ユーザーがすぐに対話する可能性のあるリソースのプリフェッチを開始します。これにより、リソースをより高速に利用できるようにするなど、より高度な動作が可能になります。 -プリフェッチトリガーは、ブロックのメイントリガーと同様に指定できますが、`prefetch` キーワードを前に付けます。ブロックのメイントリガーとプリフェッチトリガーは、セミコロン (`;`) で区切られます。 +プリフェッチトリガーは、ブロックのメイントリガーと同様に指定できますが、`prefetch`キーワードを前に付けます。ブロックのメイントリガーとプリフェッチトリガーは、セミコロン(`;`)で区切られます。 次の例では、プリフェッチはブラウザがアイドル状態になると開始され、ブロックのコンテンツは、ユーザーがプレースホルダーと対話したときにのみレンダリングされます。 @@ -279,13 +281,13 @@ Angularは、読み込みが完了すると、プレースホルダーコンテ } ``` -## `@defer` ブロックのテスト +## `@defer`ブロックのテスト -Angularは、`@defer` ブロックのテストと、テスト中のさまざまな状態のトリガーを簡素化するTestBed APIを提供しています。デフォルトでは、テスト内の `@defer` ブロックは、実際のアプリケーションで `@defer` ブロックが動作するのと同じように動作します。状態を手動でステップ実行する場合は、TestBedの構成で `@defer` ブロックの動作を `Manual` に切り替えることができます。 +Angularは、`@defer`ブロックのテストと、テスト中のさまざまな状態のトリガーを簡素化するTestBed APIを提供しています。デフォルトでは、テスト内の`@defer`ブロックは、実際のアプリケーションで`@defer`ブロックが動作するのと同じように動作します。状態を手動でステップ実行する場合は、TestBedの構成で`@defer`ブロックの動作を`Manual`に切り替えることができます。 ```angular-ts -it('さまざまな状態で `@defer` ブロックをレンダリングする', async () => { - // 手動制御のために `@defer` ブロックの動作を "一時停止" 状態から開始するように構成します。 +it('さまざまな状態で`@defer`ブロックをレンダリングする', async () => { + // 手動制御のために`@defer`ブロックの動作を"一時停止"状態から開始するように構成します。 TestBed.configureTestingModule({deferBlockBehavior: DeferBlockBehavior.Manual}); @Component({ // ... @@ -302,7 +304,7 @@ it('さまざまな状態で `@defer` ブロックをレンダリングする', class ComponentA {} // コンポーネントのfixtureを作成します。 const componentFixture = TestBed.createComponent(ComponentA); - // すべての `@defer` ブロックのfixtureを取得し、最初のブロックを取得します。 + // すべての`@defer`ブロックのfixtureを取得し、最初のブロックを取得します。 const deferBlockFixture = (await componentFixture.getDeferBlocks())[0]; // デフォルトでプレースホルダー状態をレンダリングします。 expect(componentFixture.nativeElement.innerHTML).toContain('プレースホルダー'); @@ -315,24 +317,24 @@ it('さまざまな状態で `@defer` ブロックをレンダリングする', }); ``` -## `@defer` は `NgModule` と連携しますか? +## `@defer`は`NgModule`と連携しますか? -`@defer` ブロックは、スタンドアロンコンポーネントと `NgModule` ベースのコンポーネント、ディレクティブ、パイプの両方と互換性があります。ただし、**スタンドアロンコンポーネント、ディレクティブ、パイプのみを遅延させることができます。** `NgModule` ベースの依存関係は遅延されず、先に読み込まれたバンドルに含まれます。 +`@defer`ブロックは、スタンドアロンコンポーネントと`NgModule`ベースのコンポーネント、ディレクティブ、パイプの両方と互換性があります。ただし、**スタンドアロンコンポーネント、ディレクティブ、パイプのみを遅延させることができます。**`NgModule`ベースの依存関係は遅延されず、先に読み込まれたバンドルに含まれます。 -## `@defer` は、サーバーサイドレンダリング (SSR) と静的サイト生成 (SSG) とどのように連携しますか? +## `@defer`は、サーバーサイドレンダリング(SSR)と静的サイト生成(SSG)とどのように連携しますか? -サーバーでアプリケーションをレンダリングする場合 (SSRまたはSSGを使用する場合)、`@defer` ブロックは常に `@placeholder` をレンダリングします (プレースホルダーが指定されていない場合は何もレンダリングしません)。 +デフォルトでは、サーバー上でアプリケーションをレンダリングする際(SSRまたはSSGを使用する場合)、`@defer`ブロックは常にその`@placeholder`(プレースホルダーが指定されていない場合は何も表示されません)をレンダリングし、トリガーは呼び出されません。クライアント側では、`@placeholder`の内容が水和され、トリガーがアクティブになります。 -トリガーはサーバーでは無視されます。 +サーバー上(SSRとSSGの両方)で`@defer`ブロックのメインコンテンツをレンダリングするには、[Incremental Hydration機能](/guide/incremental-hydration)を有効にして、必要なブロックの`hydrate`トリガーを構成できます。 ## ビューを遅延させるためのベストプラクティス -### ネストされた `@defer` ブロックによるカスケード読み込みを避ける +### ネストされた`@defer`ブロックによるカスケード読み込みを避ける -ネストされた `@defer` ブロックがある場合は、同時に読み込まれないように、異なるトリガーを指定する必要があります。これにより、カスケードリクエストが発生し、ページ読み込みのパフォーマンスが低下する可能性があります。 +ネストされた`@defer`ブロックがある場合は、同時に読み込まれないように、異なるトリガーを指定する必要があります。これにより、カスケードリクエストが発生し、ページ読み込みのパフォーマンスが低下する可能性があります。 ### レイアウトのシフトを避ける -初期読み込み時にユーザーのビューポートに表示されるコンポーネントを遅延させることは避けてください。これを行うと、累積レイアウトシフト (CLS) が増加するため、Core Web Vitalsに悪影響を与える可能性があります。 +初期読み込み時にユーザーのビューポートに表示されるコンポーネントを遅延させることは避けてください。これを行うと、累積レイアウトシフト(CLS)が増加するため、Core Web Vitalsに悪影響を与える可能性があります。 -必要な場合、初期ページレンダリング中にコンテンツが読み込まれる `immediate`、`timer`、`viewport`、カスタム `when` トリガーは避けてください。 +必要な場合、初期ページレンダリング中にコンテンツが読み込まれる`immediate`、`timer`、`viewport`、カスタム`when`トリガーは避けてください。 diff --git a/adev-ja/src/content/guide/templates/overview.en.md b/adev-ja/src/content/guide/templates/overview.en.md index ab996ece7..b24f33e7d 100644 --- a/adev-ja/src/content/guide/templates/overview.en.md +++ b/adev-ja/src/content/guide/templates/overview.en.md @@ -44,5 +44,5 @@ You might also be interested in the following: | [Grouping elements with ng-container](guide/templates/ng-container) | Group multiple elements together or mark a location for rendering. | | [Variables in templates](guide/templates/variables) | Learn about variable declarations. | | [Deferred loading with @defer](guide/templates/defer) | Create deferrable views with `@defer`. | -| [Expression syntax](guide/templates/expression-syntax) | Learn similarities and differences betwene Angular expressions and standard JavaScript. | +| [Expression syntax](guide/templates/expression-syntax) | Learn similarities and differences between Angular expressions and standard JavaScript. | | [Whitespace in templates](guide/templates/whitespace) | Learn how Angular handles whitespace. | diff --git a/adev-ja/src/content/guide/templates/pipes.en.md b/adev-ja/src/content/guide/templates/pipes.en.md index f7a66935e..0caaa06f7 100644 --- a/adev-ja/src/content/guide/templates/pipes.en.md +++ b/adev-ja/src/content/guide/templates/pipes.en.md @@ -260,7 +260,7 @@ export class MyCustomTransformationPipe implements PipeTransform { if (format === 'uppercase') { return msg.toUpperCase() - else { + } else { return msg } } @@ -277,18 +277,12 @@ Avoid creating impure pipes unless absolutely necessary, as they can incur a sig import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ - name: 'featuredItemsImpure', + name: 'joinNamesImpure', pure: false, }) -export class FeaturedItemsImpurePipe implements PipeTransform { - transform(value: string, format: string): string { - let msg = `My custom transformation of ${value}.` - - if (format === 'uppercase') { - return msg.toUpperCase() - else { - return msg - } +export class JoinNamesImpurePipe implements PipeTransform { + transform(names: string[]): string { + return names.join(); } } ``` diff --git a/adev-ja/src/content/guide/templates/pipes.md b/adev-ja/src/content/guide/templates/pipes.md index 5881e822a..9e9691837 100644 --- a/adev-ja/src/content/guide/templates/pipes.md +++ b/adev-ja/src/content/guide/templates/pipes.md @@ -260,7 +260,7 @@ export class MyCustomTransformationPipe implements PipeTransform { if (format === 'uppercase') { return msg.toUpperCase() - else { + } else { return msg } } @@ -277,18 +277,12 @@ export class MyCustomTransformationPipe implements PipeTransform { import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ - name: 'featuredItemsImpure', + name: 'joinNamesImpure', pure: false, }) -export class FeaturedItemsImpurePipe implements PipeTransform { - transform(value: string, format: string): string { - let msg = `My custom transformation of ${value}.` - - if (format === 'uppercase') { - return msg.toUpperCase() - else { - return msg - } +export class JoinNamesImpurePipe implements PipeTransform { + transform(names: string[]): string { + return names.join(); } } ``` diff --git a/adev-ja/src/content/guide/testing/component-harnesses-overview.md b/adev-ja/src/content/guide/testing/component-harnesses-overview.md new file mode 100644 index 000000000..a6ebb4ab7 --- /dev/null +++ b/adev-ja/src/content/guide/testing/component-harnesses-overview.md @@ -0,0 +1,30 @@ +# Component harnesses overview + +A component harness is a class that allows tests to interact with components the way an end user does via a supported API. You can create test harnesses for any component, ranging from small reusable widgets to full pages. + +Harnesses offer several benefits: +- They make tests less brittle by insulating themselves against implementation details of a component, such as its DOM structure +- They make tests become more readable and easier to maintain +- They can be used across multiple testing environments + + +// Example of test with a harness for a component called MyButtonComponent +it('should load button with exact text', async () => { + const button = await loader.getHarness(MyButtonComponentHarness); + expect(await button.getText()).toBe('Confirm'); +}); + + +Component harnesses are especially useful for shared UI widgets. Developers often write tests that depend on private implementation details of widgets, such as DOM structure and CSS classes. Those dependencies make tests brittle and hard to maintain. Harnesses offer an alternative— a supported API that interacts with the widget the same way an end-user does. Widget implementation changes now become less likely to break user tests. For example, [Angular Material](https://material.angular.io/components/categories) provides a test harness for each component in the library. + +Component harnesses support multiple testing environments. You can use the same harness implementation in both unit and end-to-end tests. Test authors only need to learn one API and component authors don't have to maintain separate unit and end-to-end test implementations. + +Many developers can be categorized by one of the following developer type categories: test authors, component harness authors, and harness environment authors. Use the table below to find the most relevant section in this guide based on these categories: + +| Developer Type | Description | Relevant Section | +|:--- | :--- | :--- | +| Test Authors | Developers that use component harnesses written by someone else to test their application. For example, this could be an app developer who uses a third-party menu component and needs to interact with the menu in a unit test. | [Using component harnesses in tests](guide/testing/using-component-harnesses) | +| Component harness authors | Developers who maintain some reusable Angular components and want to create a test harness for its users to use in their tests. For example, an author of a third party Angular component library or a developer who maintains a set of common components for a large Angular application. | [Creating component harnesses for your components](guide/testing/creating-component-harnesses ) | +| Harness environment authors | Developers who want to add support for using component harnesses in additional testing environments. For information on supported testing environments out-of-the-box, see the [test harness environments and loaders](guide/testing/using-component-harnesses#test-harness-environments-and-loaders). | [Adding support for additional testing environments](guide/testing/component-harnesses-testing-environments) | + +For the full API reference, please see the [Angular CDK's component harness API reference page](https://material.angular.io/cdk/test-harnesses/api). diff --git a/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.md b/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.md new file mode 100644 index 000000000..157ce6ba6 --- /dev/null +++ b/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.md @@ -0,0 +1,59 @@ +# Adding harness support for additional testing environments + +## Before you start + +Tip: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. + +### When does adding support for a test environment make sense? + +To use component harnesses in the following environments, you can use Angular CDK's two built-in environments: +- Unit tests +- WebDriver end-to-end tests + +To use a supported testing environment, read the [Creating harnesses for your components guide](guide/testing/creating-component-harnesses). + +Otherwise, to add support for other environments, you need to define how to interact with a DOM element and how DOM interactions work in your environment. Continue reading to learn more. + +### CDK Installation + +The [Component Dev Kit (CDK)](https://material.angular.io/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: + + + ng add @angular/cdk + + +## Creating a `TestElement` implementation + +Every test environment must define a `TestElement` implementation. The `TestElement` interface serves as an environment-agnostic representation of a DOM element. It enables harnesses to interact with DOM elements regardless of the underlying environment. Because some environments don't support interacting with DOM elements synchronously (e.g. WebDriver), all `TestElement` methods are asynchronous, returning a `Promise` with the result of the operation. + +`TestElement` offers a number of methods to interact with the underlying DOM such as `blur()`, `click()`, `getAttribute()`, and more. See the [TestElement API reference page](https://material.angular.io/cdk/test-harnesses/api#TestElement) for the full list of methods. + +The `TestElement` interface consists largely of methods that resemble methods available on `HTMLElement`. Similar methods exist in most test environments, which makes implementing the methods fairly straightforward. However, one important difference to note when implementing the `sendKeys` method, is that the key codes in the `TestKey` enum likely differ from the key codes used in the test environment. Environment authors should maintain a mapping from `TestKey` codes to the codes used in the particular testing environment. + +The [UnitTestElement](https://github.com/angular/components/blob/main/src/cdk/testing/testbed/unit-test-element.ts#L33) and [SeleniumWebDriverElement](https://github.com/angular/components/blob/main/src/cdk/testing/selenium-webdriver/selenium-webdriver-keys.ts#L16) implementations in Angular CDK serve as good examples of implementations of this interface. + +## Creating a `HarnessEnvironment` implementation +Test authors use `HarnessEnvironment` to create component harness instances for use in tests. `HarnessEnvironment` is an abstract class that must be extended to create a concrete subclass for the new environment. When supporting a new test environment, create a `HarnessEnvironment` subclass that adds concrete implementations for all abstract members. + +`HarnessEnvironment` has a generic type parameter: `HarnessEnvironment`. This parameter, `E`, represents the raw element type of the environment. For example, this parameter is Element for unit test environments. + +The following are the abstract methods that must be implemented: + +| Method | Description | +|:--- | :--- | +| `abstract getDocumentRoot(): E` | Gets the root element for the environment (e.g. `document.body`). | +| `abstract createTestElement(element: E): TestElement` | Creates a `TestElement` for the given raw element. | +| `abstract createEnvironment(element: E): HarnessEnvironment` | Creates a `HarnessEnvironment` rooted at the given raw element. | +| `abstract getAllRawElements(selector: string): Promise` | Gets all of the raw elements under the root element of the environment matching the given selector. | +| `abstract forceStabilize(): Promise` | Gets a `Promise` that resolves when the `NgZone` is stable. Additionally, if applicable, tells `NgZone` to stabilize (e.g. calling `flush()` in a `fakeAsync` test). | +| `abstract waitForTasksOutsideAngular(): Promise` | Gets a `Promise` that resolves when the parent zone of `NgZone` is stable. | + +In addition to implementing the missing methods, this class should provide a way for test authors to get `ComponentHarness` instances. You should define a protected constructor and provide a static method called `loader` that returns a `HarnessLoader` instance. This allows test authors to write code like: `SomeHarnessEnvironment.loader().getHarness(...)`. Depending on the needs of the particular environment, the class may provide several different static methods or require arguments to be passed. (e.g. the `loader` method on `TestbedHarnessEnvironment` takes a `ComponentFixture`, and the class provides additional static methods called `documentRootLoader` and `harnessForFixture`). + +The [`TestbedHarnessEnvironment`](https://github.com/angular/components/blob/main/src/cdk/testing/testbed/testbed-harness-environment.ts#L89) and [SeleniumWebDriverHarnessEnvironment](https://github.com/angular/components/blob/main/src/cdk/testing/selenium-webdriver/selenium-web-driver-harness-environment.ts#L71) implementations in Angular CDK serve as good examples of implementations of this interface. + +## Handling auto change detection +In order to support the `manualChangeDetection` and parallel APIs, your environment should install a handler for the auto change detection status. + +When your environment wants to start handling the auto change detection status it can call `handleAutoChangeDetectionStatus(handler)`. The handler function will receive a `AutoChangeDetectionStatus` which has two properties `isDisabled` and `onDetectChangesNow()`. See the [AutoChangeDetectionStatus API reference page](https://material.angular.io/cdk/test-harnesses/api#AutoChangeDetectionStatus) for more information. +If your environment wants to stop handling auto change detection status it can call `stopHandlingAutoChangeDetectionStatus()`. diff --git a/adev-ja/src/content/guide/testing/components-scenarios.en.md b/adev-ja/src/content/guide/testing/components-scenarios.en.md index 14b3bfb5b..ff10991b4 100644 --- a/adev-ja/src/content/guide/testing/components-scenarios.en.md +++ b/adev-ja/src/content/guide/testing/components-scenarios.en.md @@ -554,7 +554,7 @@ It confirms that the selected `DashboardHeroComponent` hero really does find its A *routing component* is a component that tells the `Router` to navigate to another component. The `DashboardComponent` is a *routing component* because the user can navigate to the `HeroDetailComponent` by clicking on one of the *hero buttons* on the dashboard. -Angular provides test helpers to reduce boilerplate and more effectively test code which depends HttpClient. The `provideRouter` function can be used directly in the test module as well. +Angular provides test helpers to reduce boilerplate and more effectively test code which depends `HttpClient`. The `provideRouter` function can be used directly in the test module as well. diff --git a/adev-ja/src/content/guide/testing/components-scenarios.md b/adev-ja/src/content/guide/testing/components-scenarios.md index a3ee6a466..bc5fff082 100644 --- a/adev-ja/src/content/guide/testing/components-scenarios.md +++ b/adev-ja/src/content/guide/testing/components-scenarios.md @@ -554,7 +554,7 @@ IMPORTANT: `click()`ヘルパー関数は、Angularのテストユーティリ *ルーティングコンポーネント*は、`Router`に別のコンポーネントにナビゲートするように指示するコンポーネントです。 `DashboardComponent`は、ユーザーがダッシュボードの*ヒーローボタン*の1つをクリックすることで`HeroDetailComponent`にナビゲートできるため、*ルーティングコンポーネント*です。 -Angularは、ルーターに依存するコードをより効果的にテストするために、テストヘルパーを提供しています。`provideRouter`関数はテストモジュール内でも直接使えます。 +Angularは、`HttpClient`に依存するコードをより効果的にテストするために、テストヘルパーを提供しています。`provideRouter`関数はテストモジュール内でも直接使えます。 diff --git a/adev-ja/src/content/guide/testing/creating-component-harnesses.md b/adev-ja/src/content/guide/testing/creating-component-harnesses.md new file mode 100644 index 000000000..c412dd9f0 --- /dev/null +++ b/adev-ja/src/content/guide/testing/creating-component-harnesses.md @@ -0,0 +1,276 @@ +# Creating harnesses for your components + +## Before you start + +Tip: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. + +### When does creating a test harness make sense? + +The Angular team recommends creating component test harnesses for shared components that are used in many places and have some user interactivity. This most commonly applies to widget libraries and similar reusable components. Harnesses are valuable for these cases because they provide the consumers of these shared components a well- supported API for interacting with a component. Tests that use harnesses can avoid depending on unreliable implementation details of these shared components, such as DOM structure and specific event listeners. + +For components that appear in only one place, such as a page in an application, harnesses don't provide as much benefit. In these situations, a component's tests can reasonably depend on the implementation details of this component, as the tests and components are updated at the same time. However, harnesses still provide some value if you would use the harness in both unit and end-to-end tests. + +### CDK Installation + +The [Component Dev Kit (CDK)](https://material.angular.io/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: + + + ng add @angular/cdk + + +## Extending `ComponentHarness` + +The abstract `ComponentHarness` class is the base class for all component harnesses. To create a custom component harness, extend `ComponentHarness` and implement the static property `hostSelector`. + +The `hostSelector` property identifies elements in the DOM that match this harness subclass. In most cases, the `hostSelector` should be the same as the selector of the corresponding `Component` or `Directive`. For example, consider a simple popup component: + + +@Component({ + selector: 'my-popup', + template: ` + + @if (isOpen()) { +
    + } + ` +}) +class MyPopup { + triggerText = input(''); + + isOpen = signal(false); + + toggle() { + this.isOpen.update((value) => !value); + } +} +
    + +In this case, a minimal harness for the component would look like the following: + + +class MyPopupHarness extends ComponentHarness { + static hostSelector = 'my-popup'; +} + + +While `ComponentHarness` subclasses require only the `hostSelector` property, most harnesses should also implement a static `with` method to generate `HarnessPredicate` instances. The [filtering harnesses section](guide/testing/using-component-harnesses#filtering-harnesses) covers this in more detail. + +## Finding elements in the component's DOM + +Each instance of a `ComponentHarness` subclass represents a particular instance of the corresponding component. You can access the component's host element via the `host() `method from the `ComponentHarness` base class. + +`ComponentHarness` also offers several methods for locating elements within the component's DOM. These methods are `locatorFor()`, `locatorForOptional()`, and `locatorForAll()`. These methods create functions that find elements, they do not directly find elements. This approach safeguards against caching references to out-of-date elements. For example, when an `ngIf` hides and then shows an element, the result is a new DOM element; using functions ensures that tests always reference the current state of the DOM. + +See the [ComponentHarness API reference page](https://material.angular.io/cdk/test-harnesses/api#ComponentHarness) for the full list details of the different `locatorFor` methods. + +For example, the `MyPopupHarness` example discussed above could provide methods to get the trigger and content elements as follows: + + +class MyPopupHarness extends ComponentHarness { + static hostSelector = 'my-popup'; + + /** Gets the trigger element */ + getTriggerElement = this.locatorFor('button'); + + /** Gets the content element. */ + getContentElement = this.locatorForOptional('.my-popup-content'); +} + + +## Working with `TestElement` instances + +`TestElement` is an abstraction designed to work across different test environments (Unit tests, WebDriver, etc). When using harnesses, you should perform all DOM interaction via this interface. Other means of accessing DOM elements, such as `document.querySelector()`, do not work in all test environments. + +`TestElement` has a number of methods to interact with the underlying DOM, such as `blur()`, `click()`, `getAttribute()`, and more. See the [TestElement API reference page](https://material.angular.io/cdk/test-harnesses/api#TestElement) for the full list of methods. + +Do not expose `TestElement` instances to harness users unless it's an element the component consumer defines directly, such as the component's host element. Exposing `TestElement` instances for internal elements leads users to depend on a component's internal DOM structure. + +Instead, provide more narrow-focused methods for specific actions the end-user may take or particular state they may observe. For example, `MyPopupHarness` from previous sections could provide methods like `toggle` and `isOpen`: + + +class MyPopupHarness extends ComponentHarness { + static hostSelector = 'my-popup'; + + protected getTriggerElement = this.locatorFor('button'); + protected getContentElement = this.locatorForOptional('.my-popup-content'); + + /** Toggles the open state of the popup. */ + async toggle() { + const trigger = await this.getTriggerElement(); + return trigger.click(); + } + + /** Checks if the popup us open. */ + async isOpen() { + const content = await this.getContentElement(); + return !!content; + } +} + + +## Loading harnesses for subcomponents + +Larger components often compose sub-components. You can reflect this structure in a component's harness as well. Each of the `locatorFor` methods on `ComponentHarness` has an alternate signature that can be used for locating sub-harnesses rather than elements. + +See the [ComponentHarness API reference page](https://material.angular.io/cdk/test-harnesses/api#ComponentHarness) for the full list of the different locatorFor methods. + +For example, consider a menu build using the popup from above: + + +@Directive({ + selector: 'my-menu-item' +}) +class MyMenuItem {} + +@Component({ + selector: 'my-menu', + template: ` + + + + ` +}) +class MyMenu { + triggerText = input(''); + + @ContentChildren(MyMenuItem) items: QueryList; +} + + +The harness for `MyMenu` can then take advantage of other harnesses for `MyPopup` and `MyMenuItem`: + + +class MyMenuHarness extends ComponentHarness { + static hostSelector = 'my-menu'; + + protected getPopupHarness = this.locatorFor(MyPopupHarness); + + /** Gets the currently shown menu items (empty list if menu is closed). */ + getItems = this.locatorForAll(MyMenuItemHarness); + + /** Toggles open state of the menu. */ + async toggle() { + const popupHarness = await this.getPopupHarness(); + return popupHarness.toggle(); + } +} + +class MyMenuItemHarness extends ComponentHarness { + static hostSelector = 'my-menu-item'; +} + + +## Filtering harness instances with `HarnessPredicate` +When a page contains multiple instances of a particular component, you may want to filter based on some property of the component to get a particular component instance. For example, you may want a button with some specific text, or a menu with a specific ID. The `HarnessPredicate` class can capture criteria like this for a `ComponentHarness` subclass. While the test author is able to construct `HarnessPredicate` instances manually, it's easier when the `ComponentHarness` subclass provides a helper method to construct predicates for common filters. + +You should create a static `with()` method on each `ComponentHarness` subclass that returns a `HarnessPredicate` for that class. This allows test authors to write easily understandable code, e.g. `loader.getHarness(MyMenuHarness.with({selector: '#menu1'}))`. In addition to the standard selector and ancestor options, the `with` method should add any other options that make sense for the particular subclass. + +Harnesses that need to add additional options should extend the `BaseHarnessFilters` interface and additional optional properties as needed. `HarnessPredicate` provides several convenience methods for adding options: `stringMatches()`, `addOption()`, and `add()`. See the [HarnessPredicate API page](https://material.angular.io/cdk/test-harnesses/api#HarnessPredicate) for the full description. + +For example, when working with a menu it is useful to filter based on trigger text and to filter menu items based on their text: + + +interface MyMenuHarnessFilters extends BaseHarnessFilters { + /** Filters based on the trigger text for the menu. */ + triggerText?: string | RegExp; +} + +interface MyMenuItemHarnessFilters extends BaseHarnessFilters { + /** Filters based on the text of the menu item. */ + text?: string | RegExp; +} + +class MyMenuHarness extends ComponentHarness { + static hostSelector = 'my-menu'; + + /** Creates a `HarnessPredicate` used to locate a particular `MyMenuHarness`. */ + static with(options: MyMenuHarnessFilters): HarnessPredicate { + return new HarnessPredicate(MyMenuHarness, options) + .addOption('trigger text', options.triggerText, + (harness, text) => HarnessPredicate.stringMatches(harness.getTriggerText(), text)); + } + + protected getPopupHarness = this.locatorFor(MyPopupHarness); + + /** Gets the text of the menu trigger. */ + async getTriggerText(): Promise { + const popupHarness = await this.getPopupHarness(); + return popupHarness.getTriggerText(); + } + ... +} + +class MyMenuItemHarness extends ComponentHarness { + static hostSelector = 'my-menu-item'; + + /** Creates a `HarnessPredicate` used to locate a particular `MyMenuItemHarness`. */ + static with(options: MyMenuItemHarnessFilters): HarnessPredicate { + return new HarnessPredicate(MyMenuItemHarness, options) + .addOption('text', options.text, + (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text)); + } + + /** Gets the text of the menu item. */ + async getText(): Promise { + const host = await this.host(); + return host.text(); + } +} + + +You can pass a `HarnessPredicate` instead of a `ComponentHarness` class to any of the APIs on `HarnessLoader`, `LocatorFactory`, or `ComponentHarness`. This allows test authors to easily target a particular component instance when creating a harness instance. It also allows the harness author to leverage the same `HarnessPredicate` to enable more powerful APIs on their harness class. For example, consider the `getItems` method on the `MyMenuHarness` shown above. Adding a filtering API allows users of the harness to search for particular menu items: + + +class MyMenuHarness extends ComponentHarness { + static hostSelector = 'my-menu'; + + /** Gets a list of items in the menu, optionally filtered based on the given criteria. */ + async getItems(filters: MyMenuItemHarnessFilters = {}): Promise { + const getFilteredItems = this.locatorForAll(MyMenuItemHarness.with(filters)); + return getFilteredItems(); + } + ... +} + + +## Creating `HarnessLoader` for elements that use content projection + +Some components project additional content into the component's template. See the [content projection guide](guide/components/content-projection) for more information. + +Add a `HarnessLoader` instance scoped to the element containing the `` when you create a harness for a component that uses content projection. This allows the user of the harness to load additional harnesses for whatever components were passed in as content. `ComponentHarness` has several methods that can be used to create HarnessLoader instances for cases like this: `harnessLoaderFor()`, `harnessLoaderForOptional()`, `harnessLoaderForAll()`. See the [HarnessLoader interface API reference page](https://material.angular.io/cdk/test-harnesses/api#HarnessLoader) for more details. + +For example, the `MyPopupHarness` example from above can extend `ContentContainerComponentHarness` to add support to load harnesses within the `` of the component. + + +class MyPopupHarness extends ContentContainerComponentHarness { + static hostSelector = 'my-popup'; +} + + +## Accessing elements outside of the component's host element + +There are times when a component harness might need to access elements outside of its corresponding component's host element. For example, code that displays a floating element or pop-up often attaches DOM elements directly to the document body, such as the `Overlay` service in Angular CDK. + +In this case, `ComponentHarness` provides a method that can be used to get a `LocatorFactory` for the root element of the document. The `LocatorFactory` supports most of the same APIs as the `ComponentHarness` base class, and can then be used to query relative to the document's root element. + +Consider if the `MyPopup` component above used the CDK overlay for the popup content, rather than an element in its own template. In this case, `MyPopupHarness` would have to access the content element via `documentRootLocatorFactory()` method that gets a locator factory rooted at the document root. + + +class MyPopupHarness extends ComponentHarness { + static hostSelector = 'my-popup'; + + /** Gets a `HarnessLoader` whose root element is the popup's content element. */ + async getHarnessLoaderForContent(): Promise { + const rootLocator = this.documentRootLocatorFactory(); + return rootLocator.harnessLoaderFor('my-popup-content'); + } +} + + +## Waiting for asynchronous tasks + +The methods on `TestElement` automatically trigger Angular's change detection and wait for tasks inside the `NgZone`. In most cases no special effort is required for harness authors to wait on asynchronous tasks. However, there are some edge cases where this may not be sufficient. + +Under some circumstances, Angular animations may require a second cycle of change detection and subsequent `NgZone` stabilization before animation events are fully flushed. In cases where this is needed, the `ComponentHarness` offers a `forceStabilize()` method that can be called to do the second round. + +You can use `NgZone.runOutsideAngular()` to schedule tasks outside of NgZone. Call the `waitForTasksOutsideAngular()` method on the corresponding harness if you need to explicitly wait for tasks outside `NgZone` since this does not happen automatically. diff --git a/adev-ja/src/content/guide/testing/using-component-harnesses.md b/adev-ja/src/content/guide/testing/using-component-harnesses.md new file mode 100644 index 000000000..3eaae5847 --- /dev/null +++ b/adev-ja/src/content/guide/testing/using-component-harnesses.md @@ -0,0 +1,207 @@ +# Using component harnesses in tests + +## Before you start + +Tip: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. + +### CDK Installation + +The [Component Dev Kit (CDK)](https://material.angular.io/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: + + + ng add @angular/cdk + + +## Test harness environments and loaders + +You can use component test harnesses in different test environments. Angular CDK supports two built-in environments: +- Unit tests with Angular's `TestBed` +- End-to-end tests with [WebDriver](https://developer.mozilla.org/en-US/docs/Web/WebDriver) + + +Each environment provides a harness loader. The loader creates the harness instances you use throughout your tests. See below for more specific guidance on supported testing environments. + +Additional testing environments require custom bindings. See the [adding harness support for additional testing environments guide](guide/testing/component-harnesses-testing-environments) for more information. + +### Using the loader from `TestbedHarnessEnvironment` for unit tests + +For unit tests you can create a harness loader from [TestbedHarnessEnvironment](https://material.angular.io/cdk/test-harnesses/api#TestbedHarnessEnvironment). This environment uses a [component fixture](api/core/testing/ComponentFixture) created by Angular's `TestBed`. + +To create a harness loader rooted at the fixture's root element, use the `loader()` method: + + +const fixture = TestBed.createComponent(MyComponent); + +// Create a harness loader from the fixture +const loader = TestbedHarnessEnvironment.loader(fixture); +... + +// Use the loader to get harness instances +const myComponentHarness = await loader.getHarness(MyComponent); + + +To create a harness loader for harnesses for elements that fall outside the fixture, use the `documentRootLoader()` method. For example, code that displays a floating element or pop-up often attaches DOM elements directly to the document body, such as the `Overlay` service in Angular CDK. + +You can also create a harness loader directly with `harnessForFixture()` for a harness at that fixture's root element directly. + +### Using the loader from `SeleniumWebDriverHarnessEnvironment` for end-to-end tests + +For WebDriver-based end-to-end tests you can create a harness loader with `SeleniumWebDriverHarnessEnvironment`. + +Use the `loader()` method to get the harness loader instance for the current HTML document, rooted at the document's root element. This environment uses a WebDriver client. + + +let wd: webdriver.WebDriver = getMyWebDriverClient(); +const loader = SeleniumWebDriverHarnessEnvironment.loader(wd); +... +const myComponentHarness = await loader.getHarness(MyComponent); + + +## Using a harness loader + +Harness loader instances correspond to a specific DOM element and are used to create component harness instances for elements under that specific element. + +To get `ComponentHarness` for the first instance of the element, use the `getHarness()` method. You get all `ComponentHarness` instances, use the `getAllHarnesses()` method. + + +// Get harness for first instance of the element +const myComponentHarness = await loader.getHarness(MyComponent); + +// Get harnesses for all instances of the element +const myComponentHarnesses = await loader.getHarnesses(MyComponent); + + +As an example, consider a reusable dialog-button component that opens a dialog on click. It contains the following components, each with a corresponding harness: +- `MyDialogButton` (composes the `MyButton` and `MyDialog` with a convenient API) +- `MyButton` (a standard button component) +- `MyDialog` (a dialog appended to `document.body` by `MyDialogButton` upon click) + +The following test loads harnesses for each of these components: + + +let fixture: ComponentFixture; +let loader: HarnessLoader; +let rootLoader: HarnessLoader; + +beforeEach(() => { + fixture = TestBed.createComponent(MyDialogButton); + loader = TestbedHarnessEnvironment.loader(fixture); + rootLoader = TestbedHarnessEnvironment.documentRootLoader(fixture); +}); + +it('loads harnesses', async () => { + // Load a harness for the bootstrapped component with `harnessForFixture` + dialogButtonHarness = + await TestbedHarnessEnvironment.harnessForFixture(fixture, MyDialogButtonHarness); + // The button element is inside the fixture's root element, so we use `loader`. + const buttonHarness = await loader.getHarness(MyButtonHarness); + // Click the button to open the dialog + await buttonHarness.click(); + // The dialog is appended to `document.body`, outside of the fixture's root element, + // so we use `rootLoader` in this case. + const dialogHarness = await rootLoader.getHarness(MyDialogHarness); + // ... make some assertions +}); + + +### Harness behavior in different environments + +Harnesses may not behave exactly the same in all environments. Some differences are unavoidable between the real user interaction versus the simulated events generated in unit tests. Angular CDK makes a best effort to normalize the behavior to the extent possible. + +### Interacting with child elements + +To interact with elements below the root element of this harness loader, use the `HarnessLoader` instance of a child element. For the first instance of the child element, use the `getChildLoader()` method. For all instances of the child element, use the `getAllChildLoaders()` method. + + +const myComponentHarness = await loader.getHarness(MyComponent); + +// Get loader for first instance of child element with '.child' selector +const childLoader = await myComponentHarness.getLoader('.child'); + +// Get loaders for all instances of child elements with '.child' selector +const allChildLoaders = await myComponentHarness.getAllChildLoaders('.child'); + + +### Filtering harnesses + +When a page contains multiple instances of a particular component, you may want to filter based on some property of the component to get a particular component instance. You can use a harness predicate, a class used to associate a `ComponentHarness` class with predicates functions that can be used to filter component instances, to do so. + +When you ask a `HarnessLoader` for a harness, you're actually providing a HarnessQuery. A query can be one of two things: +- A harness constructor. This just gets that harness +- A `HarnessPredicate`, which gets harnesses that are filtered based on one or more conditions + +`HarnessPredicate` does support some base filters (selector, ancestor) that work on anything that extends `ComponentHarness`. + + +// Example of loading a MyButtonComponentHarness with a harness predicate +const disabledButtonPredicate = new HarnessPredicate(MyButtonComponentHarness, {selector: '[disabled]'}); +const disabledButton = await loader.getHarness(disabledButtonPredicate); + + +However it's common for harnesses to implement a static `with()` method that accepts component-specific filtering options and returns a `HarnessPredicate`. + + +// Example of loading a MyButtonComponentHarness with a specific selector +const button = await loader.getHarness(MyButtonComponentHarness.with({selector: 'btn'})) + + +For more details refer to the specific harness documentation since additional filtering options are specific to each harness implementation. + +## Using test harness APIs + +While every harness defines an API specific to its corresponding component, they all share a common base class, [ComponentHarness](https://material.angular.io/cdk/test-harnesses/api#ComponentHarness). This base class defines a static property, `hostSelector`, that matches the harness class to instances of the component in the DOM. + +Beyond that, the API of any given harness is specific to its corresponding component; refer to the component's documentation to learn how to use a specific harness. + +As an example, the following is a test for a component that uses the [Angular Material slider component harness](https://material.angular.io/components/slider/api#MatSliderHarness): + + +it('should get value of slider thumb', async () => { + const slider = await loader.getHarness(MatSliderHarness); + const thumb = await slider.getEndThumb(); + expect(await thumb.getValue()).toBe(50); +}); + + +## Interop with Angular change detection + +By default, test harnesses runs Angular's [change detection](https://angular.dev/best-practices/runtime-performance) before reading the state of a DOM element and after interacting with a DOM element. + +There may be times that you need finer-grained control over change detection in your tests. such as checking the state of a component while an async operation is pending. In these cases use the `manualChangeDetection` function to disable automatic handling of change detection for a block of code. + + +it('checks state while async action is in progress', async () => { + const buttonHarness = loader.getHarness(MyButtonHarness); + await manualChangeDetection(async () => { + await buttonHarness.click(); + fixture.detectChanges(); + // Check expectations while async click operation is in progress. + expect(isProgressSpinnerVisible()).toBe(true); + await fixture.whenStable(); + // Check expectations after async click operation complete. + expect(isProgressSpinnerVisible()).toBe(false); + }); +}); + + +Almost all harness methods are asynchronous and return a `Promise` to support the following: +- Support for unit tests +- Support for end-to-end tests +- Insulate tests against changes in asynchronous behavior + +The Angular team recommends using [await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) to improve the test readability. Calling `await` blocks the execution of your test until the associated `Promise` resolves. + +Occasionally, you may want to perform multiple actions simultaneously and wait until they're all done rather than performing each action sequentially. For example, read multiple properties of a single component. In these situations use the `parallel` function to parallelize the operations. The parallel function works similarly to `Promise.all`, while also optimizing change detection checks. + + +it('reads properties in parallel', async () => { + const checkboxHarness = loader.getHarness(MyCheckboxHarness); + // Read the checked and intermediate properties simultaneously. + const [checked, indeterminate] = await parallel(() => [ + checkboxHarness.isChecked(), + checkboxHarness.isIndeterminate() + ]); + expect(checked).toBe(false); + expect(indeterminate).toBe(true); +}); + diff --git a/adev-ja/src/content/guide/testing/utility-apis.en.md b/adev-ja/src/content/guide/testing/utility-apis.en.md index 2bca12952..a76e4a985 100644 --- a/adev-ja/src/content/guide/testing/utility-apis.en.md +++ b/adev-ja/src/content/guide/testing/utility-apis.en.md @@ -105,7 +105,7 @@ Here are the most useful methods for testers. | `autoDetectChanges` | Set this to `true` when you want the fixture to detect changes automatically.
    When autodetect is `true`, the test fixture calls `detectChanges` immediately after creating the component. Then it listens for pertinent zone events and calls `detectChanges` accordingly. When your test code modifies component property values directly, you probably still have to call `fixture.detectChanges` to trigger data binding updates.
    The default is `false`. Testers who prefer fine control over test behavior tend to keep it `false`. | | `checkNoChanges` | Do a change detection run to make sure there are no pending changes. Throws an exceptions if there are. | | `isStable` | If the fixture is currently *stable*, returns `true`. If there are async tasks that have not completed, returns `false`. | -| `whenStable` | Returns a promise that resolves when the fixture is stable.
    To resume testing after completion of asynchronous activity or asynchronous change detection, hook that promise. See [whenStable](guide/testing/components-scenarios#when-stable). | +| `whenStable` | Returns a promise that resolves when the fixture is stable.
    To resume testing after completion of asynchronous activity or asynchronous change detection, hook that promise. See [whenStable](guide/testing/components-scenarios#whenstable). | | `destroy` | Trigger component destruction. | #### `DebugElement` diff --git a/adev-ja/src/content/guide/testing/utility-apis.md b/adev-ja/src/content/guide/testing/utility-apis.md index b69291b84..f61c69dd8 100644 --- a/adev-ja/src/content/guide/testing/utility-apis.md +++ b/adev-ja/src/content/guide/testing/utility-apis.md @@ -105,7 +105,7 @@ type MetadataOverride = { | `autoDetectChanges` | `true` に設定すると、fixture が変更を自動的に検出します。
    自動検出が `true` の場合、テスト fixture はコンポーネントの作成直後に `detectChanges` を呼び出します。その後、適切なゾーンイベントを監視し、それに応じて `detectChanges` を呼び出します。テストコードでコンポーネントのプロパティ値を直接変更する場合は、それでもデータバインディングの更新をトリガーするために、`fixture.detectChanges` を呼び出す必要がある可能性があります。
    デフォルトは `false` です。テストの動作を細かく制御したいテスターは、通常、これを `false` のままにします。 | | `checkNoChanges` | 変更検知を実行して、保留中の変更がないことを確認します。変更がある場合は、例外をスローします。 | | `isStable` | fixture が現在 *安定* している場合は、`true` を返します。非同期タスクがまだ完了していない場合は、`false` を返します。 | -| `whenStable` | fixture が安定したら解決される Promise を返します。
    非同期アクティビティまたは非同期的な変更検知の完了後にテストを再開するには、その Promise をフックします。[whenStable](guide/testing/components-scenarios#when-stable) を参照してください。 | +| `whenStable` | fixture が安定したら解決される Promise を返します。
    非同期アクティビティまたは非同期的な変更検知の完了後にテストを再開するには、その Promise をフックします。[whenStable](guide/testing/components-scenarios#whenstable) を参照してください。 | | `destroy` | コンポーネントの破棄をトリガーします。 | #### `DebugElement` diff --git a/adev-ja/src/content/introduction/essentials/dependency-injection.en.md b/adev-ja/src/content/introduction/essentials/dependency-injection.en.md index 60fef13cf..606fb5efb 100644 --- a/adev-ja/src/content/introduction/essentials/dependency-injection.en.md +++ b/adev-ja/src/content/introduction/essentials/dependency-injection.en.md @@ -6,7 +6,7 @@ When you need to share logic between components, Angular leverages the design pa ## What are services? -Services are reusable pieces of code that can be injected +Services are reusable pieces of code that can be injected. Similar to defining a component, services are comprised of the following: diff --git a/adev-ja/src/content/introduction/essentials/templates.en.md b/adev-ja/src/content/introduction/essentials/templates.en.md index 0a4336a3d..1ff4e6d9c 100644 --- a/adev-ja/src/content/introduction/essentials/templates.en.md +++ b/adev-ja/src/content/introduction/essentials/templates.en.md @@ -23,7 +23,7 @@ export class TodoListItem { When Angular renders the component, you see: ```html -

    Profile file pro_programmer_123

    +

    Profile for pro_programmer_123

    ``` Angular automatically keeps the binding up-to-date when the value of the signal changes. Building on @@ -36,7 +36,7 @@ this.userName.set('cool_coder_789'); The rendered page updates to reflect the new value: ```html -

    Profile file cool_coder_789

    +

    Profile for cool_coder_789

    ``` ## Setting dynamic properties and attributes @@ -46,7 +46,7 @@ Angular supports binding dynamic values into DOM properties with square brackets ```angular-ts @Component({ /*...*/ - // Set the `disabled` property of the button based on the value of `isAccountDisabled`. + // Set the `disabled` property of the button based on the value of `isValidUserId`. template: ``, }) export class UserProfile { diff --git a/adev-ja/src/content/introduction/essentials/templates.md b/adev-ja/src/content/introduction/essentials/templates.md index ea5c98ff1..d7d37482a 100644 --- a/adev-ja/src/content/introduction/essentials/templates.md +++ b/adev-ja/src/content/introduction/essentials/templates.md @@ -23,7 +23,7 @@ export class TodoListItem { Angularがコンポーネントをレンダリングすると、以下が表示されます。 ```html -

    Profile file pro_programmer_123

    +

    Profile for pro_programmer_123

    ``` シグナルの値が変更されると、Angularはバインディングを自動的に最新の状態に保ちます。 @@ -36,7 +36,7 @@ this.userName.set('cool_coder_789'); レンダリングされたページは新しい値を反映して更新されます。 ```html -

    Profile file cool_coder_789

    +

    Profile for cool_coder_789

    ``` ## 動的なプロパティと属性の設定 @@ -46,7 +46,7 @@ Angularは、角括弧を使用して動的な値をDOMプロパティにバイ ```angular-ts @Component({ /*...*/ - // `isAccountDisabled`の値に基づいて、ボタンの`disabled`プロパティを設定します。 + // `isValidUserId`の値に基づいて、ボタンの`disabled`プロパティを設定します。 template: ``, }) export class UserProfile { diff --git a/adev-ja/src/content/reference/configs/angular-compiler-options.md b/adev-ja/src/content/reference/configs/angular-compiler-options.md index 8df4d77bc..09731158a 100644 --- a/adev-ja/src/content/reference/configs/angular-compiler-options.md +++ b/adev-ja/src/content/reference/configs/angular-compiler-options.md @@ -213,6 +213,10 @@ See [troubleshooting template errors](tools/cli/template-typecheck#troubleshooti When you use the Angular CLI command `ng new --strict`, it is set to `true` in the new project's configuration. +### `strictStandalone` + +When `true`, reports an error if a component, directive, or pipe is not standalone. + ### `trace` When `true`, prints extra information while compiling templates. diff --git a/adev-ja/src/content/reference/errors/NG01203.en.md b/adev-ja/src/content/reference/errors/NG01203.en.md index 89152f92c..7aa92fe12 100644 --- a/adev-ja/src/content/reference/errors/NG01203.en.md +++ b/adev-ja/src/content/reference/errors/NG01203.en.md @@ -23,4 +23,4 @@ As described above, your control was expected to have a value accessor, but was 1. Are you using a custom form control declared inside an `NgModule`? if so, make sure you are **importing** the `NgModule`. 1. Are you using `ngModel` with a third-party custom form control? Check whether that control provides a value accessor. If not, use **`ngDefaultControl`** on the control's element. 1. Are you **testing** a custom form control? Be sure to configure your testbed to know about the control. You can do so with `Testbed.configureTestingModule`. -1. Are you using **Nx and Module Federation** with Webpack? Your `webpack.config.js` may require [extra configuration](https://github.com/angular/angular/issues/43821#issuecomment-1054845431) to ensure the forms package is shared. +1. Are you using **Nx and Module Federation** with webpack? Your `webpack.config.js` may require [extra configuration](https://github.com/angular/angular/issues/43821#issuecomment-1054845431) to ensure the forms package is shared. diff --git a/adev-ja/src/content/reference/errors/NG01203.md b/adev-ja/src/content/reference/errors/NG01203.md index 4bfc12e18..7b9511d05 100644 --- a/adev-ja/src/content/reference/errors/NG01203.md +++ b/adev-ja/src/content/reference/errors/NG01203.md @@ -23,4 +23,4 @@ providers: [ 1. `NgModule`内で宣言されたカスタムフォームコントロールを使用していますか? その場合は、**インポート**していることを確認してください。 1. サードパーティのカスタムフォームコントロールで`ngModel`を使用していますか? そのコントロールが値アクセサを提供しているかどうかを確認してください。提供していない場合は、コントロールの要素に**`ngDefaultControl`**を使用してください。 1. カスタムフォームコントロールを**テスト**していますか? テストベッドがコントロールについて認識していることを確認してください。これは`Testbed.configureTestingModule`を使用して実行できます。 -1. **Nxおよびモジュールフェデレーション**をWebpackで使用していますか? `webpack.config.js`には、フォームパッケージが共有されるようにするための[追加の構成](https://github.com/angular/angular/issues/43821#issuecomment-1054845431)が必要になる場合があります。 +1. **Nxおよびモジュールフェデレーション**をwebpackで使用していますか? `webpack.config.js`には、フォームパッケージが共有されるようにするための[追加の構成](https://github.com/angular/angular/issues/43821#issuecomment-1054845431)が必要になる場合があります。 diff --git a/adev-ja/src/content/reference/errors/NG0750.md b/adev-ja/src/content/reference/errors/NG0750.md new file mode 100644 index 000000000..0fff34532 --- /dev/null +++ b/adev-ja/src/content/reference/errors/NG0750.md @@ -0,0 +1,6 @@ +# @defer dependencies failed to load + +This error occurs when loading dependencies for a `@defer` block fails (typically due to poor network conditions) and no `@error` block has been configured to handle the failure state. Having no `@error` block in this scenario may create a poor user experience. + +## Debugging the error +Verify that you added `@error` blocks to your `@defer` blocks to handle failure states. \ No newline at end of file diff --git a/adev-ja/src/content/reference/errors/NG0913.en.md b/adev-ja/src/content/reference/errors/NG0913.en.md index 083e7664d..7100277a4 100644 --- a/adev-ja/src/content/reference/errors/NG0913.en.md +++ b/adev-ja/src/content/reference/errors/NG0913.en.md @@ -20,7 +20,7 @@ Use the image URL provided in the console warning to find the `` element in ### Disabling Image Performance Warnings Both warnings can be disabled individually, site-wide, using a provider at the root of your application: - +```typescript providers: [ { provide: IMAGE_CONFIG, @@ -30,5 +30,4 @@ providers: [ } }, ], - - +``` \ No newline at end of file diff --git a/adev-ja/src/content/reference/errors/NG0913.md b/adev-ja/src/content/reference/errors/NG0913.md index 592f42c55..d9746dfcc 100644 --- a/adev-ja/src/content/reference/errors/NG0913.md +++ b/adev-ja/src/content/reference/errors/NG0913.md @@ -20,7 +20,7 @@ ### 画像パフォーマンス警告を無効にする方法 両方の警告は、アプリケーションのルートでプロバイダーを使用して、個別にまたはサイト全体で無効にできます。 - +```typescript providers: [ { provide: IMAGE_CONFIG, @@ -30,5 +30,4 @@ providers: [ } }, ], - - +``` diff --git a/adev-ja/src/content/reference/errors/overview.en.md b/adev-ja/src/content/reference/errors/overview.en.md index 5af4d62b5..05c41bbaf 100644 --- a/adev-ja/src/content/reference/errors/overview.en.md +++ b/adev-ja/src/content/reference/errors/overview.en.md @@ -21,6 +21,7 @@ | `NG0505` | [No hydration info in server response](errors/NG0505) | | `NG0506` | [NgZone remains unstable](errors/NG0506) | | `NG0507` | [HTML content was altered after SSR](errors/NG0507) | +| `NG0750` | [@defer dependencies failed to load](errors/NG0750) | | `NG0910` | [Unsafe bindings on an iframe element](errors/NG0910) | | `NG0912` | [Component ID generation collision](errors/NG0912) | | `NG0955` | [Track expression resulted in duplicated keys for a given collection](errors/NG0955) | @@ -29,7 +30,7 @@ | `NG01203` | [Missing value accessor](errors/NG01203) | | `NG02200` | [Missing Iterable Differ](errors/NG02200) | | `NG02800` | [JSONP support in HttpClient configuration](errors/NG02800) | -| `NG05000` | [Hydration with unsupported Zone.js instance.](errors/NG05000) | +| `NG05000` | [Hydration with unsupported Zone.js instance.](errors/NG05000) | | `NG05104` | [Root element was not found.](errors/NG05104) | ## Compiler errors diff --git a/adev-ja/src/content/reference/errors/overview.md b/adev-ja/src/content/reference/errors/overview.md index b52b04b36..0742785d8 100644 --- a/adev-ja/src/content/reference/errors/overview.md +++ b/adev-ja/src/content/reference/errors/overview.md @@ -21,6 +21,7 @@ | `NG0505` | [No hydration info in server response](errors/NG0505) | | `NG0506` | [NgZone remains unstable](errors/NG0506) | | `NG0507` | [HTML content was altered after SSR](errors/NG0507) | +| `NG0750` | [@defer dependencies failed to load](errors/NG0750) | | `NG0910` | [Unsafe bindings on an iframe element](errors/NG0910) | | `NG0912` | [Component ID generation collision](errors/NG0912) | | `NG0955` | [Track expression resulted in duplicated keys for a given collection](errors/NG0955) | diff --git a/adev-ja/src/content/reference/migrations/cleanup-unused-imports.md b/adev-ja/src/content/reference/migrations/cleanup-unused-imports.md new file mode 100644 index 000000000..3191acaf2 --- /dev/null +++ b/adev-ja/src/content/reference/migrations/cleanup-unused-imports.md @@ -0,0 +1,38 @@ +# Clean up unused imports + +As of version 19, Angular reports when a component's `imports` array contains symbols that aren't used in its template. + +Running this schematic will clean up all unused imports within the project. + +Run the schematic using the following command: + + + +ng generate @angular/core:cleanup-unused-imports + + + +#### Before + + +import { Component } from '@angular/core'; +import { UnusedDirective } from './unused'; + +@Component({ + template: 'Hello', + imports: [UnusedDirective], +}) +export class MyComp {} + + +#### After + + +import { Component } from '@angular/core'; + +@Component({ + template: 'Hello', + imports: [], +}) +export class MyComp {} + diff --git a/adev-ja/src/content/reference/migrations/outputs.md b/adev-ja/src/content/reference/migrations/outputs.md new file mode 100644 index 000000000..9ca85a326 --- /dev/null +++ b/adev-ja/src/content/reference/migrations/outputs.md @@ -0,0 +1,96 @@ +# Migration to output function + +Angular introduced an improved API for outputs in v17.3 that is considered +production ready as of v19. This API mimics the `input()` API but is not based on Signals. +Read more about custom events output function and its benefits in the [dedicated guide](guide/components/outputs). + +To support existing projects that would like to use output function, the Angular team +provides an automated migration that converts `@Output` custom events to the new `output()` API. + +Run the schematic using the following command: + +```bash +ng generate @angular/core:output-migration +``` + +## What does the migration change? + +1. `@Output()` class members are updated to their `output()` equivalent. +2. Imports in the file of components or directives, at Typescript module level, are updated as well. +3. Migrates the APIs functions like `event.next()`, which use is not recommended, to `event.emit()` and removes `event.complete()` calls. + +**Before** + +```typescript +import {Component, Output} from '@angular/core'; + +@Component({ + template: `` +}) +export class MyComponent { + @Output() someChange = new EventEmitter(); + + someMethod(value: string): void { + this.someChange.emit(value); + } +} +``` + +**After** + +```typescript +import {Component, output} from '@angular/core'; + +@Component({ + template: `` +}) +export class MyComponent { + readonly someChange = output(); + + someMethod(value: string): void { + this.someChange.emit(value); + } +} +``` + +## Configuration options + +The migration supports a few options for fine tuning the migration to your specific needs. + +### `--path` + +If not specified, the migration will ask you for a path and update your whole Angular CLI workspace. +You can limit the migration to a specific sub-directory using this option. + +### `--analysis-dir` + +In large projects you may use this option to reduce the amount of files being analyzed. +By default, the migration analyzes the whole workspace, regardless of the `--path` option, in +order to update all references affected by an `@Output()` migration. + +With this option, you can limit analysis to a sub-folder. Note that this means that any +references outside this directory are silently skipped, potentially breaking your build. + +Use these options as shown below: + +```bash +ng generate @angular/core:output-migration --path src/app/sub-folder +``` + +## Exceptions + +In some cases, the migration will not touch the code. +One of these excpetions is the case where the event is used with a `pipe()` method. +The following code won't be migrated: + +```typescript +export class MyDialogComponent { + @Output() close = new EventEmitter(); + doSome(): void { + this.close.complete(); + } + otherThing(): void { + this.close.pipe(); + } +} +``` \ No newline at end of file diff --git a/adev-ja/src/content/reference/migrations/overview.md b/adev-ja/src/content/reference/migrations/overview.md index d047fc664..132beae45 100644 --- a/adev-ja/src/content/reference/migrations/overview.md +++ b/adev-ja/src/content/reference/migrations/overview.md @@ -15,10 +15,16 @@ Learn about how you can migrate your existing angular project to the latest feat Convert eagerly loaded component routes to lazy loaded ones. This allows the build process to split production bundles into smaller chunks, to load less JavaScript at initial page load. - + Convert existing `@Input` fields to the new signal input API that is now production ready. - + + Convert existing `@Output` custom events to the new output function that is now production ready. + + Convert existing decorator query fields to the improved signal queries API. The API is now production ready. + + Clean up unused imports in your project. + diff --git a/adev-ja/src/content/reference/migrations/standalone.md b/adev-ja/src/content/reference/migrations/standalone.md index e3f383af0..587d36dc8 100644 --- a/adev-ja/src/content/reference/migrations/standalone.md +++ b/adev-ja/src/content/reference/migrations/standalone.md @@ -63,7 +63,7 @@ You should run these migrations in the order given. ### Convert declarations to standalone -In this mode, the migration converts all components, directives and pipes to standalone by setting `standalone: true` and adding dependencies to their `imports` array. +In this mode, the migration converts all components, directives and pipes to standalone by removing `standalone: false` and adding dependencies to their `imports` array. HELPFUL: The schematic ignores NgModules which bootstrap a component during this step because they are likely root modules used by `bootstrapModule` rather than the standalone-compatible `bootstrapApplication`. The schematic converts these declarations automatically as a part of the ["Switch to standalone bootstrapping API"](#switch-to-standalone-bootstrapping-api) step. @@ -84,6 +84,7 @@ export class SharedModule {} @Component({ selector: 'greeter', template: '
    Hello
    ', + standalone: false, }) export class GreeterComponent { showGreeting = true; @@ -106,7 +107,6 @@ export class SharedModule {} @Component({ selector: 'greeter', template: '
    Hello
    ', - standalone: true, imports: [NgIf] }) export class GreeterComponent { @@ -150,7 +150,7 @@ export class ImporterModule {} ### Switch to standalone bootstrapping API -This step converts any usages of `bootstrapModule` to the new, standalone-based `bootstrapApplication`. It also switches the root component to `standalone: true` and deletes the root NgModule. If the root module has any `providers` or `imports`, the migration attempts to copy as much of this configuration as possible into the new bootstrap call. +This step converts any usages of `bootstrapModule` to the new, standalone-based `bootstrapApplication`. It also removes `standalone: false` from the root component and deletes the root NgModule. If the root module has any `providers` or `imports`, the migration attempts to copy as much of this configuration as possible into the new bootstrap call. **Before:** @@ -168,7 +168,11 @@ export class AppModule {} ```typescript // ./app/app.component.ts -@Component({ selector: 'app', template: 'hello' }) +@Component({ + selector: 'app', + template: 'hello', + standalone: false, +}) export class AppComponent {} ``` @@ -189,7 +193,10 @@ platformBrowser().bootstrapModule(AppModule).catch(e => console.error(e)); ```typescript // ./app/app.component.ts -@Component({ selector: 'app', template: 'hello', standalone: true }) +@Component({ + selector: 'app', + template: 'hello' +}) export class AppComponent {} ``` diff --git a/adev-ja/src/content/reference/releases.en.md b/adev-ja/src/content/reference/releases.en.md index 111181232..c8fc4124b 100644 --- a/adev-ja/src/content/reference/releases.en.md +++ b/adev-ja/src/content/reference/releases.en.md @@ -74,9 +74,9 @@ HELPFUL: Approximate dates are offered as general guidance and are subject to ch | Version | Date | |:--------|:-------------------| -| v18.1 | Week of 2024-07-08 | -| v18.2 | Week of 2024-08-12 | -| v19.0 | Week of 2024-11-19 | +| v19.1 | Week of 2025-01-13 | +| v19.2 | Week of 2025-02-24 | +| v20.0 | Week of 2025-05-19 | ### Support window @@ -93,11 +93,11 @@ The following table provides the status for Angular versions under support. | Version | Status | Released | Active ends | LTS ends | |:--------|:-------|:-----------|:------------|:-----------| -| ^18.0.0 | Active | 2024-05-22 | 2024-11-15 | 2025-11-15 | +| ^19.0.0 | Active | 2024-11-19 | 2025-05-19 | 2026-05-19 | +| ^18.0.0 | LTS | 2024-05-22 | 2024-11-19 | 2025-11-19 | | ^17.0.0 | LTS | 2023-11-08 | 2024-05-08 | 2025-05-15 | -| ^16.0.0 | LTS | 2023-05-03 | 2023-11-08 | 2024-11-08 | -Angular versions v2 to v15 are no longer supported. +Angular versions v2 to v16 are no longer supported. ### LTS fixes diff --git a/adev-ja/src/content/reference/releases.md b/adev-ja/src/content/reference/releases.md index 96f493d62..8aed3a520 100644 --- a/adev-ja/src/content/reference/releases.md +++ b/adev-ja/src/content/reference/releases.md @@ -74,9 +74,9 @@ HELPFUL: 概算の日付は一般的なガイダンスとして提供されて | バージョン | 日付 | |:--------|:-------------------| -| v18.1 | 2024-07-08 の週 | -| v18.2 | 2024-08-12 の週 | -| v19.0 | 2024-11-19 の週 | +| v19.1 | Week of 2025-01-13 | +| v19.2 | Week of 2025-02-24 | +| v20.0 | Week of 2025-05-19 | ### サポート期間 @@ -93,11 +93,11 @@ HELPFUL: 概算の日付は一般的なガイダンスとして提供されて | バージョン | ステータス | リリース済み | アクティブ終了 | LTS 終了 | |:--------|:-------|:-----------|:------------|:-----------| -| ^18.0.0 | アクティブ | 2024-05-22 | 2024-11-15 | 2025-11-15 | +| ^19.0.0 | Active | 2024-11-19 | 2025-05-19 | 2026-05-19 | +| ^18.0.0 | LTS | 2024-05-22 | 2024-11-19 | 2025-11-19 | | ^17.0.0 | LTS | 2023-11-08 | 2024-05-08 | 2025-05-15 | -| ^16.0.0 | LTS | 2023-05-03 | 2023-11-08 | 2024-11-08 | -Angularバージョンv2からv15はサポートされなくなりました。 +Angularバージョンv2からv16はサポートされなくなりました。 ### LTSの修正 diff --git a/adev-ja/src/content/reference/roadmap.en.md b/adev-ja/src/content/reference/roadmap.en.md index dab005941..6d506dcad 100644 --- a/adev-ja/src/content/reference/roadmap.en.md +++ b/adev-ja/src/content/reference/roadmap.en.md @@ -37,7 +37,7 @@ Start developing with the latest Angular features from our roadmap. This list re * [Signal inputs](/guide/signals/inputs) * [Model inputs](/guide/signals/model) * [Signal queries](/guide/signals/queries) -* [Function-based outputs](/guide/components/output-fn) +* [Function-based outputs](/guide/components/outputs) ## Improving the Angular developer experience @@ -154,7 +154,7 @@ This section represents explorations and prototyping of potential future project As part of this initiative, the language service automatically imports components and pipes in standalone and NgModule-based apps. Additionally, we've added a template diagnostic to highlight unused imports in standalone components, which should help make application bundles smaller. - + We've released the support for local template variables in Angular, see [`@let` docs](https://angular.dev/api/core/@let) for additional information. diff --git a/adev-ja/src/content/reference/roadmap.md b/adev-ja/src/content/reference/roadmap.md index 9335c96aa..d39a07ad0 100644 --- a/adev-ja/src/content/reference/roadmap.md +++ b/adev-ja/src/content/reference/roadmap.md @@ -37,7 +37,7 @@ * [シグナル入力](/guide/signals/inputs) * [モデル入力](/guide/signals/model) * [シグナルクエリ](/guide/signals/queries) -* [関数ベースの出力](/guide/components/output-fn) +* [関数ベースの出力](/guide/components/output) ## Angular開発者体験の改善 @@ -154,7 +154,7 @@ As part of this initiative, the language service automatically imports components and pipes in standalone and NgModule-based apps. Additionally, we've added a template diagnostic to highlight unused imports in standalone components, which should help make application bundles smaller. - + We've released the support for local template variables in Angular, see [`@let` docs](https://angular.dev/api/core/@let) for additional information. diff --git a/adev-ja/src/content/reference/versions.en.md b/adev-ja/src/content/reference/versions.en.md index 112a15aab..71c8caceb 100644 --- a/adev-ja/src/content/reference/versions.en.md +++ b/adev-ja/src/content/reference/versions.en.md @@ -9,6 +9,7 @@ This table covers [Angular versions under active support](reference/releases#act | Angular | Node.js | TypeScript | RxJS | | ------------------ | ------------------------------------ | -------------- | ------------------ | +| 19.1.x | ^18.19.1 \|\| ^20.11.1 \|\| ^22.0.0 | >=5.5.0 <5.8.0 | ^6.5.3 \|\| ^7.4.0 | | 19.0.x | ^18.19.1 \|\| ^20.11.1 \|\| ^22.0.0 | >=5.5.0 <5.7.0 | ^6.5.3 \|\| ^7.4.0 | | 18.1.x \|\| 18.2.x | ^18.19.1 \|\| ^20.11.1 \|\| ^22.0.0 | >=5.4.0 <5.6.0 | ^6.5.3 \|\| ^7.4.0 | | 18.0.x | ^18.19.1 \|\| ^20.11.1 \|\| ^22.0.0 | >=5.4.0 <5.5.0 | ^6.5.3 \|\| ^7.4.0 | diff --git a/adev-ja/src/content/reference/versions.md b/adev-ja/src/content/reference/versions.md index 20b5ebb4d..77bd5e54d 100644 --- a/adev-ja/src/content/reference/versions.md +++ b/adev-ja/src/content/reference/versions.md @@ -9,6 +9,7 @@ Node.js、TypeScript、RxJSのバージョンを示しています。 | Angular | Node.js | TypeScript | RxJS | | ------------------ | ------------------------------------ | -------------- | ------------------ | +| 19.1.x | ^18.19.1 \|\| ^20.11.1 \|\| ^22.0.0 | >=5.5.0 <5.8.0 | ^6.5.3 \|\| ^7.4.0 | | 19.0.x | ^18.19.1 \|\| ^20.11.1 \|\| ^22.0.0 | >=5.5.0 <5.7.0 | ^6.5.3 \|\| ^7.4.0 | | 18.1.x \|\| 18.2.x | ^18.19.1 \|\| ^20.11.1 \|\| ^22.0.0 | >=5.4.0 <5.6.0 | ^6.5.3 \|\| ^7.4.0 | | 18.0.x | ^18.19.1 \|\| ^20.11.1 \|\| ^22.0.0 | >=5.4.0 <5.5.0 | ^6.5.3 \|\| ^7.4.0 | diff --git a/adev-ja/src/content/tools/cli/build-system-migration.md b/adev-ja/src/content/tools/cli/build-system-migration.md index bc9e353b9..f8f53e2fe 100644 --- a/adev-ja/src/content/tools/cli/build-system-migration.md +++ b/adev-ja/src/content/tools/cli/build-system-migration.md @@ -12,7 +12,7 @@ This new build system is stable and fully supported for use with Angular applica You can migrate to the new build system with applications that use the `browser` builder. If using a custom builder, please refer to the documentation for that builder on possible migration options. -IMPORTANT: The existing Webpack-based build system is still considered stable and fully supported. +IMPORTANT: The existing webpack-based build system is still considered stable and fully supported. Applications can continue to use the `browser` builder and projects can opt-out of migrating during an update. ## For new applications @@ -29,7 +29,7 @@ HELPFUL: Remember to remove any CommonJS assumptions in the application server c ### Automated migration (Recommended) -The automated migration will adjust both the application configuration within `angular.json` as well as code and stylesheets to remove previous Webpack-specific feature usage. +The automated migration will adjust both the application configuration within `angular.json` as well as code and stylesheets to remove previous webpack-specific feature usage. While many changes can be automated and most applications will not require any further changes, each application is unique and there may be some manual changes required. After the migration, please attempt a build of the application as there could be new errors that will require adjustments within the code. The errors will attempt to provide solutions to the problem when possible and the later sections of this guide describe some of the more common situations that you may encounter. @@ -49,7 +49,7 @@ The migration does the following: * Updates configuration accordingly. * Merges `tsconfig.server.json` with `tsconfig.app.json` and adds the TypeScript option `"esModuleInterop": true` to ensure `express` imports are [ESM compliant](#esm-default-imports-vs-namespace-imports). * Updates application server code to use new bootstrapping and output directory structure. -* Removes any Webpack-specific builder stylesheet usage such as the tilde or caret in `@import`/`url()` and updates the configuration to provide equivalent behavior +* Removes any webpack-specific builder stylesheet usage such as the tilde or caret in `@import`/`url()` and updates the configuration to provide equivalent behavior * Converts to use the new lower dependency `@angular/build` Node.js package if no other `@angular-devkit/build-angular` usage is found. ### Manual migration @@ -134,7 +134,7 @@ The following list discusses all the `browser` builder options that will need to - `ngswConfigPath` should be renamed to `serviceWorker`. If the application is not using SSR currently, this should be the final step to allow `ng build` to function. -After executing `ng build` for the first time, there may be new warnings or errors based on behavioral differences or application usage of Webpack-specific features. +After executing `ng build` for the first time, there may be new warnings or errors based on behavioral differences or application usage of webpack-specific features. Many of the warnings will provide suggestions on how to remedy that problem. If it appears that a warning is incorrect or the solution is not apparent, please open an issue on [GitHub](https://github.com/angular/angular-cli/issues). Also, the later sections of this guide provide additional information on several specific cases as well as current known issues. @@ -179,19 +179,22 @@ ng serve You can continue to use the [command line options](/cli/serve) you have used in the past with the development server. +HELPFUL: With the development server, you may see a small Flash of Unstyled Content (FOUC) on startup as the server initializes. +The development server attempts to defer processing of stylesheets until first use to improve rebuild times. +This will not occur in builds outside the development server. + ### Hot module replacement Hot Module Replacement (HMR) is a technique used by development servers to avoid reloading the entire page when only part of an application is changed. The changes in many cases can be immediately shown in the browser which allows for an improved edit/refresh cycle while developing an application. While general JavaScript-based hot module replacement (HMR) is currently not supported, several more specific forms of HMR are available: -- **global stylesheets** (default) -- **component stylesheet** (default) -- **component template** (experimental opt-in) +- **global stylesheet** (`styles` build option) +- **component stylesheet** (inline and file-based) +- **component template** (inline and file-based) -The stylesheet HMR capabilities are automatically enabled and require no code or configuration changes to use. -Angular provides HMR support for both file-based (`styleUrl`/`styleUrls`) and inline (`styles`) component styles. +The HMR capabilities are automatically enabled and require no code or configuration changes to use. +Angular provides HMR support for both file-based (`templateUrl`/`styleUrl`/`styleUrls`) and inline (`template`/`styles`) component styles and templates. The build system will attempt to compile and process the minimal amount of application code when it detects a stylesheet only change. -In many cases, no JavaScript/TypeScript processing will be required. If preferred, the HMR capabilities can be disabled by setting the `hmr` development server option to `false`. This can also be changed on the command line via: @@ -202,14 +205,6 @@ ng serve --no-hmr
    -In addition to fully supported component stylesheet HMR, Angular provides **experimental** support for component template HMR. -Template HMR also requires no application code changes but currently requires the use of the `NG_HMR_TEMPLATES=1` environment variable to enable. - -IMPORTANT: Component **template** HMR is experimental and is not enabled by default. -Currently, only file-based (`styleUrl`) templates are supported and any inline template changes will cause a full page reload. -When manually enabled, there may be cases where the browser is not fully synchronized with the application code and a restart of the development server may be required. -If you encounter an issue while using this feature, please [report the bug](https://github.com/angular/angular-cli/issues) to help the Angular team stabilize the feature. - ### Vite as a development server The usage of Vite in the Angular CLI is currently within a _development server capacity only_. Even without using the underlying Vite build system, Vite provides a full-featured development server with client side support that has been bundled into a low dependency npm package. This makes it an ideal candidate to provide comprehensive development server functionality. The current development server process uses the new build system to generate a development build of the application in memory and passes the results to Vite to serve the application. The usage of Vite, much like the Webpack-based development server, is encapsulated within the Angular CLI `dev-server` builder and currently cannot be directly configured. @@ -279,7 +274,7 @@ An example is as follows: ... "define": { "SOME_NUMBER": "5", - "ANOTHER": "''this is a string literal, note the extra single quotes'", + "ANOTHER": "'this is a string literal, note the extra single quotes'", "REFERENCE": "globalThis.someValue.noteTheAbsentSingleQuotes" } } @@ -538,4 +533,4 @@ IMPORTANT: Avoiding the use of modules with non-local side effects (outside of p Report issues and feature requests on [GitHub](https://github.com/angular/angular-cli/issues). -Please provide a minimal reproduction where possible to aid the team in addressing issues. +Please provide a minimal reproduction where possible to aid the team in addressing issues. \ No newline at end of file diff --git a/adev-ja/src/content/tools/cli/build.md b/adev-ja/src/content/tools/cli/build.md index 568675dc4..426835b46 100644 --- a/adev-ja/src/content/tools/cli/build.md +++ b/adev-ja/src/content/tools/cli/build.md @@ -8,7 +8,7 @@ Angular CLI includes four builders typically used as `build` targets: | Builder | Purpose | | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `@angular-devkit/build-angular:browser` | Bundles a client-side application for use in a browser with [Webpack](https://webpack.js.org/). | +| `@angular-devkit/build-angular:browser` | Bundles a client-side application for use in a browser with [webpack](https://webpack.js.org/). | | `@angular-devkit/build-angular:browser-esbuild` | Bundles a client-side application for use in a browser with [esbuild](https://esbuild.github.io/). See [`browser-esbuild` documentation](tools/cli/build-system-migration#manual-migration-to-the-compatibility-builder) for more information. | | `@angular-devkit/build-angular:application` | Builds an application with a client-side bundle, a Node server, and build-time prerendered routes with [esbuild](https://esbuild.github.io/). | | `@angular-devkit/build-angular:ng-packagr` | Builds an Angular library adhering to [Angular Package Format](tools/libraries/angular-package-format). | diff --git a/adev-ja/src/content/tools/cli/deployment.md b/adev-ja/src/content/tools/cli/deployment.md index 49b6cd5f4..d7e202ea7 100644 --- a/adev-ja/src/content/tools/cli/deployment.md +++ b/adev-ja/src/content/tools/cli/deployment.md @@ -6,12 +6,12 @@ Angularアプリケーションをリモートサーバーにデプロイする AngularのCLIコマンドである`ng deploy`はあなたのプロジェクトに紐づいた`deploy` [CLI builder](guide/cli-builder)を実行します。 多数のサードパーティのビルダーが異なるプラットフォームで機能するよう実装しています。 -`ng add`によって、それらのいずれかをあなたのプロジェクトに追加することが可能です。 +`ng add`によって、それらのいずれかをあなたのプロジェクトに追加できます。 デプロイ機能が入ったパッケージを追加すると、選択されたプロジェクトに対する`deploy`セクションを伴うワークスペースの設定(`angular.json`ファイル)が自動的に更新されます。 その後、そのプロジェクトにデプロイするために`ng deploy`コマンドを使うことが可能です。 -例えば、以下のコマンドは[Firebase](https://firebase.google.com/)にプロジェクトを自動的にデプロイすることが可能です。 +例えば、以下のコマンドは[Firebase](https://firebase.google.com/)にプロジェクトを自動的にデプロイできます。 @@ -36,7 +36,7 @@ ng deploy | [GitHub pages](https://pages.github.com) | [`ng add angular-cli-ghpages`](https://npmjs.org/package/angular-cli-ghpages) | | [Amazon Cloud S3](https://aws.amazon.com/s3/?nc2=h_ql_prod_st_s3) | [`ng add @jefiozie/ngx-aws-deploy`](https://www.npmjs.com/package/@jefiozie/ngx-aws-deploy) | -もし自己管理されたサーバーにデプロイする場合や、お気に入りのクラウドプラットフォームのビルダーがない場合、`ng deploy`コマンドを使うことを許容する[ビルダーを作成する](tools/cli/cli-builder)か、アプリケーションを手動でデプロイする方法を学ぶためのこのガイドを読み通すかのどちらかの方法を取る事が可能です。 +もし自己管理されたサーバーにデプロイする場合や、お気に入りのクラウドプラットフォームのビルダーがない場合、`ng deploy`コマンドを使うことを許容する[ビルダーを作成する](tools/cli/cli-builder)か、アプリケーションを手動でデプロイする方法を学ぶためのこのガイドを読み通すか、どちらかの方法を取る事が可能です。 ## リモートサーバーへの手動デプロイ @@ -71,7 +71,7 @@ Angularのルーターを迂回して、ブラウザは`/users/42`に対する 静的なサーバーは`http://my-app.test/`に対するリクエストを受け取ると決まって`index.html`を返します。 しかし、デフォルトでほとんどサーバーは`index.html`を代わりに返すよう設定されて*いないかぎり*`http://my-app.test/users/42`を拒否して`404 - Not Found`エラーを返します。 -フォールバックルートを設定するか、サーバー上で404ページを`index.html`にする設定することで、Angularはディープリンクに関するサービスを提供し、正しいルートを表示することができます。 +フォールバックルートを設定するか、サーバー上で404ページを`index.html`にする設定することで、Angularはディープリンクに関するサービスを提供し、正しいルートを表示できます。 いくつかのサーバーはこのフォールバックの挙動を"Single-Page Application"(SPA)モードと呼びます。 一度ブラウザがアプリケーションをロードすると、Angularのルーターはどのページにあるのかを判断するためにURLを読み込み、`/users/42`を正しく表示しようとします。 @@ -90,7 +90,7 @@ Angularのルーターを迂回して、ブラウザは`/users/42`に対する ## プロダクションの最適化 -`ng build`は特に設定を行わない限り`production`設定を使います。この設定はビルド最適化機能を有効にします。 +`ng build`は特に設定しない限り`production`設定を使います。この設定はビルド最適化機能を有効にします。 | 機能 | 詳細 | |:--- |:--- | @@ -112,7 +112,7 @@ CLIのビルドオプションとそれらの効果についてより多く知 * より詳細なエラーメッセージ。 * [デバッグ関数](api#core-global)および[Angular DevTools](tools/devtools)をサポートするグローバルな`ng`変数のような追加のデバッグユーティリティ。 -これらの機能は開発中は便利ですが、アプリに追加のコードが必要で、プロダクションでは望まれません。 +これらの機能は開発中は便利ですが、アプリケーションに追加のコードが必要で、プロダクションでは望まれません。 エンドユーザーのためのバンドルサイズにネガティブな影響を与えないよう、これらの機能を安全に使うために、Angular CLIは プロダクションをバンドリングする際のバンドルから開発時のみのコードを削除します。 @@ -130,5 +130,5 @@ ng build --deploy-url /my/assets `--deploy-url`の効果と目的は[``](guide/routing/common-router-tasks)と重なります。両者とも初期のスクリプト、スタイルシート、遅延して読み込まれるスクリプト、cssリソースのために使用できます。 -``実行時に一か所で定義することができる``とは違い、`--deploy-url`はビルド時にアプリケーションでハードコーディングされる必要があります。 +``実行時に一か所で定義できる`とは違い、`--deploy-url`はビルド時にアプリケーションでハードコーディングされる必要があります。 可能であれば``の方が好ましいです。 diff --git a/adev-ja/src/content/tools/cli/serve.md b/adev-ja/src/content/tools/cli/serve.md index c288f008c..448b952e1 100644 --- a/adev-ja/src/content/tools/cli/serve.md +++ b/adev-ja/src/content/tools/cli/serve.md @@ -74,7 +74,7 @@ For example, to divert all calls for `http://localhost:4200/api` to a server run 1. To run the development server with this proxy configuration, call `ng serve`. Edit the proxy configuration file to add configuration options; following are some examples. -For a description of all options, see [webpack DevServer documentation](https://webpack.js.org/configuration/dev-server/#devserverproxy). +For a detailed description of all options, refer to the [webpack DevServer documentation](https://webpack.js.org/configuration/dev-server/#devserverproxy) when using `@angular-devkit/build-angular:browser`, or the [Vite DevServer documentation](https://vite.dev/config/server-options#server-proxy) when using `@angular-devkit/build-angular:browser-esbuild` or `@angular-devkit/build-angular:application`. NOTE: If you edit the proxy configuration file, you must relaunch the `ng serve` process to make your changes effective. diff --git a/adev-ja/src/content/tools/cli/template-typecheck.md b/adev-ja/src/content/tools/cli/template-typecheck.md index f2476811a..4fbd75ddb 100644 --- a/adev-ja/src/content/tools/cli/template-typecheck.md +++ b/adev-ja/src/content/tools/cli/template-typecheck.md @@ -116,7 +116,7 @@ Unless otherwise commented, each following option is set to the value for `stric | `strictInputTypes` | Whether the assignability of a binding expression to the `@Input()` field is checked. Also affects the inference of directive generic types. | | `strictInputAccessModifiers` | Whether access modifiers such as `private`/`protected`/`readonly` are honored when assigning a binding expression to an `@Input()`. If disabled, the access modifiers of the `@Input` are ignored; only the type is checked. This option is `false` by default, even with `strictTemplates` set to `true`. | | `strictNullInputTypes` | Whether `strictNullChecks` is honored when checking `@Input()` bindings \(per `strictInputTypes`\). Turning this off can be useful when using a library that was not built with `strictNullChecks` in mind. | -| `strictAttributeTypes` | Whether to check `@Input()` bindings that are made using text attributes. For example, \(setting the `disabled` property to the string `'true'`\) vs \(setting the `disabled` property to the boolean `true`\). | +| `strictAttributeTypes` | Whether to check `@Input()` bindings that are made using text attributes. For example, `` \(setting the `disabled` property to the string `'true'`\) vs `` \(setting the `disabled` property to the boolean `true`\). | | `strictSafeNavigationTypes` | Whether the return type of safe navigation operations \(for example, `user?.name` will be correctly inferred based on the type of `user`\). If disabled, `user?.name` will be of type `any`. | | `strictDomLocalRefTypes` | Whether local references to DOM elements will have the correct type. If disabled `ref` will be of type `any` for ``. | | `strictOutputEventTypes` | Whether `$event` will have the correct type for event bindings to component/directive an `@Output()`, or to animation events. If disabled, it will be `any`. | diff --git a/adev-ja/src/content/tools/language-service.md b/adev-ja/src/content/tools/language-service.md index d5f009a39..5b99eb5b2 100644 --- a/adev-ja/src/content/tools/language-service.md +++ b/adev-ja/src/content/tools/language-service.md @@ -135,7 +135,7 @@ Angular language service can be used with Neovim by using the [nvim-lspconfig](h 1. [Install nvim-lspconfig](https://github.com/neovim/nvim-lspconfig?tab=readme-ov-file#install) -2. [Configure angularls for nvim-lspconfig](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#angularls) +2. [Configure angularls for nvim-lspconfig](https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#angularls) ## How the Language Service works @@ -155,4 +155,4 @@ The Angular Language Services then looks at `data.---` within its context, asks ## More information * For more in-depth information on the implementation, see the [Angular Language Service source](https://github.com/angular/angular/blob/main/packages/language-service/src) -* For more on the design considerations and intentions, see [design documentation here](https://github.com/angular/vscode-ng-language-service/wiki/Design) +* For more on the design considerations and intentions, see [design documentation here](https://github.com/angular/vscode-ng-language-service/wiki/Design) \ No newline at end of file diff --git a/adev-ja/src/content/tools/libraries/angular-package-format.md b/adev-ja/src/content/tools/libraries/angular-package-format.md index 6f13abee0..7ac53be0a 100644 --- a/adev-ja/src/content/tools/libraries/angular-package-format.md +++ b/adev-ja/src/content/tools/libraries/angular-package-format.md @@ -12,7 +12,7 @@ You can find the versions of the specification prior to v13 in this [google doc] ## Why specify a package format? -In today's JavaScript landscape, developers consume packages in many different ways, using many different toolchains \(Webpack, rollup, esbuild, etc.\). +In today's JavaScript landscape, developers consume packages in many different ways, using many different toolchains \(webpack, Rollup, esbuild, etc.\). These tools may understand and require different inputs - some tools may be able to process the latest ES language version, while others may benefit from directly consuming an older ES version. The Angular distribution format supports all of the commonly used development tools and workflows, and adds emphasis on optimizations that result either in smaller application payload size or faster development iteration cycle \(build time\). @@ -256,7 +256,7 @@ By default, EcmaScript Modules are side-effectful: importing from a module ensur This is often undesirable, as most side-effectful code in typical modules is not truly side-effectful, but instead only affects specific symbols. If those symbols are not imported and used, it's often desirable to remove them in an optimization process known as tree-shaking, and the side-effectful code can prevent this. -Build tools such as Webpack support a flag which allows packages to declare that they do not depend on side-effectful code at the top level of their modules, giving the tools more freedom to tree-shake code from the package. +Build tools such as webpack support a flag which allows packages to declare that they do not depend on side-effectful code at the top level of their modules, giving the tools more freedom to tree-shake code from the package. The end result of these optimizations should be smaller bundle size and better code distribution in bundle chunks after code-splitting. This optimization can break your code if it contains non-local side-effects - this is however not common in Angular applications and it's usually a sign of bad design. The recommendation is for all packages to claim the side-effect free status by setting the `sideEffects` property to `false`, and that developers follow the [Angular Style Guide](/style-guide) which naturally results in code without non-local side-effects. @@ -339,7 +339,7 @@ Because of this, the Angular team often uses the language level specifier as a s ### Bundle -An artifact in the form of a single JS file, produced by a build tool \(for example, [Webpack](https://webpack.js.org) or [Rollup](https://rollupjs.org)\) that contains symbols originating in one or more modules. +An artifact in the form of a single JS file, produced by a build tool \(for example, [webpack](https://webpack.js.org) or [Rollup](https://rollupjs.org)\) that contains symbols originating in one or more modules. Bundles are a browser-specific workaround that reduce network strain that would be caused if browsers were to start downloading hundreds if not tens of thousands of files. Node.js typically doesn't use bundles. Common bundle formats are UMD and System.register. diff --git a/adev-ja/src/content/tools/libraries/creating-libraries.md b/adev-ja/src/content/tools/libraries/creating-libraries.md index 8c9044410..ca79a6e8b 100644 --- a/adev-ja/src/content/tools/libraries/creating-libraries.md +++ b/adev-ja/src/content/tools/libraries/creating-libraries.md @@ -285,7 +285,7 @@ The plugin is to be imported from `@angular/compiler-cli/linker/babel`. The Angular linker Babel plugin supports build caching, meaning that libraries only need to be processed by the linker a single time, regardless of other npm operations. -Example of integrating the plugin into a custom [Webpack](https://webpack.js.org) build by registering the linker as a [Babel](https://babeljs.io) plugin using [babel-loader](https://webpack.js.org/loaders/babel-loader/#options). +Example of integrating the plugin into a custom [webpack](https://webpack.js.org) build by registering the linker as a [Babel](https://babeljs.io) plugin using [babel-loader](https://webpack.js.org/loaders/babel-loader/#options). diff --git a/adev-ja/src/content/tutorials/first-app/intro/README.md b/adev-ja/src/content/tutorials/first-app/intro/README.md index d34cb6e9b..5db4d662b 100644 --- a/adev-ja/src/content/tutorials/first-app/intro/README.md +++ b/adev-ja/src/content/tutorials/first-app/intro/README.md @@ -66,6 +66,7 @@ You are free to use any tool you prefer to build apps with Angular. We recommend 1. [Visual Studio Code](https://code.visualstudio.com/) 2. As an optional, but recommended step you can further improve your developer experience by installing the [Angular Language Service](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template) +3. [WebStorm](https://www.jetbrains.com/webstorm/) diff --git a/adev-ja/src/content/tutorials/first-app/steps/07-dynamic-template-values/README.md b/adev-ja/src/content/tutorials/first-app/steps/07-dynamic-template-values/README.md index 3953ca970..9c19a1e66 100644 --- a/adev-ja/src/content/tutorials/first-app/steps/07-dynamic-template-values/README.md +++ b/adev-ja/src/content/tutorials/first-app/steps/07-dynamic-template-values/README.md @@ -27,13 +27,13 @@ In the code editor: 1. Navigate to `src/app/housing-location/housing-location.component.ts` 1. In the template property of the `@Component` decorator, replace the existing HTML markup with the following code: - + - In this updated template code you have used property binding to bind the `housingLocation.photo` to the `src` attribute. The `alt` attribute uses interpolation to give more context to the alt text of the image. + In this updated template code you have used property binding to bind the `housingLocation.photo` to the `src` attribute. The `alt` attribute uses interpolation to give more context to the alt text of the image. - You use interpolation to include the values for `name`, `city` and `state` of the `housingLocation` property. + You use interpolation to include the values for `name`, `city` and `state` of the `housingLocation` property. - + 1. Save all changes. diff --git a/origin b/origin index e7566c3c4..2ec826dfd 160000 --- a/origin +++ b/origin @@ -1 +1 @@ -Subproject commit e7566c3c475560616f97de2ab3c8f8d6f83be015 +Subproject commit 2ec826dfdce8d8b57ffca58c018ab7e3082c28e6 diff --git a/tools/adev-patches/add-global-styles.patch b/tools/adev-patches/add-global-styles.patch index 82df2cbbb..d3955cf4f 100644 --- a/tools/adev-patches/add-global-styles.patch +++ b/tools/adev-patches/add-global-styles.patch @@ -1,13 +1,13 @@ diff --git a/adev/src/local-styles.scss b/adev/src/local-styles.scss -index 4dcf2e82aa..ba311a65f9 100644 +index 2c83a2ad4a..9d9b28112a 100644 --- a/adev/src/local-styles.scss +++ b/adev/src/local-styles.scss -@@ -1 +1,15 @@ --@import './styles/xterm'; -\ No newline at end of file -+@import './styles/xterm'; -+ +@@ -1,3 +1,17 @@ + @use './styles/xterm'; + + @include xterm.xterm(); +// adev-ja overrides ++ +docs-viewer { + // `balance` is not good for Japanese headings. + h1, @@ -16,8 +16,8 @@ index 4dcf2e82aa..ba311a65f9 100644 + h4, + h5, + h6 { -+ word-break: auto-phrase; ++ word-break: auto-phrase; + } -+ } -+ ++} ++ \ No newline at end of file diff --git a/tools/adev-patches/localize-home.patch b/tools/adev-patches/localize-home.patch index b2c73d377..117a38767 100644 --- a/tools/adev-patches/localize-home.patch +++ b/tools/adev-patches/localize-home.patch @@ -5,9 +5,9 @@ index 53d930d66d..732d40ec53 100644 @@ -3,8 +3,8 @@
    - + -

    Angular v19 is here!

    --

    Watch the all-new developer event now.

    +-

    Read about our newest release.

    +

    Angular v19 が利用可能です!

    +

    今すぐ開発者向けイベントを見よう!

    diff --git a/tools/adev-patches/replace-canonical-host.patch b/tools/adev-patches/replace-canonical-host.patch index 23a11fc8a..8843490aa 100644 --- a/tools/adev-patches/replace-canonical-host.patch +++ b/tools/adev-patches/replace-canonical-host.patch @@ -1,8 +1,8 @@ diff --git a/adev/src/app/core/services/header.service.ts b/adev/src/app/core/services/header.service.ts -index ee21c0a837..afe9b7819c 100644 +index ac27b818c4..9b34429ee9 100644 --- a/adev/src/app/core/services/header.service.ts +++ b/adev/src/app/core/services/header.service.ts -@@ -1,7 +1,7 @@ +@@ -9,7 +9,7 @@ import {DOCUMENT} from '@angular/common'; import {Injectable, inject} from '@angular/core'; diff --git a/tools/adev-patches/set-current-major-verion.patch b/tools/adev-patches/set-current-major-verion.patch index e3d69c51a..ec0a2ff46 100644 --- a/tools/adev-patches/set-current-major-verion.patch +++ b/tools/adev-patches/set-current-major-verion.patch @@ -1,13 +1,13 @@ diff --git a/adev/src/app/app.config.ts b/adev/src/app/app.config.ts -index 1bc572a030..40345f5292 100644 +index 52ab0a523c..6cf5be631c 100644 --- a/adev/src/app/app.config.ts +++ b/adev/src/app/app.config.ts -@@ -77,7 +77,7 @@ export const appConfig: ApplicationConfig = { - provideAnimationsAsync(), +@@ -80,7 +80,7 @@ export const appConfig: ApplicationConfig = { + provideEnvironmentInitializer(() => inject(AnalyticsService)), { provide: CURRENT_MAJOR_VERSION, - useValue: Number(VERSION.major), + useValue: 19, }, {provide: ENVIRONMENT, useValue: environment}, - { + {provide: ErrorHandler, useClass: CustomErrorHandler}, diff --git a/tools/adev-patches/translate-top-level-banner.patch b/tools/adev-patches/translate-top-level-banner.patch index 2fa2b56f1..16dc29f6a 100644 --- a/tools/adev-patches/translate-top-level-banner.patch +++ b/tools/adev-patches/translate-top-level-banner.patch @@ -1,12 +1,13 @@ diff --git a/adev/src/app/app.component.html b/adev/src/app/app.component.html -index 07ffbaf51b..19e4798fac 100644 +index e589f35912..828b3c43b7 100644 --- a/adev/src/app/app.component.html +++ b/adev/src/app/app.component.html -@@ -1,6 +1,6 @@ +@@ -2,7 +2,7 @@ + @defer (when isBrowser) { -- -+ +- ++ } - +
    diff --git a/tools/adev-patches/translate-tutorial-label.patch b/tools/adev-patches/translate-tutorial-label.patch index ff96e9cc4..b6344c4ae 100644 --- a/tools/adev-patches/translate-tutorial-label.patch +++ b/tools/adev-patches/translate-tutorial-label.patch @@ -1,10 +1,10 @@ diff --git a/adev/src/app/features/tutorial/tutorial.component.ts b/adev/src/app/features/tutorial/tutorial.component.ts -index a254df6d80..4ff592b981 100644 +index 5ed9051ae2..bb24ca4242 100644 --- a/adev/src/app/features/tutorial/tutorial.component.ts +++ b/adev/src/app/features/tutorial/tutorial.component.ts -@@ -44,7 +44,7 @@ import {SplitResizerHandler} from './split-resizer-handler.service'; - import {TutorialType} from '@angular/docs'; - import {TutorialNavigationData, TutorialNavigationItem} from '@angular/docs'; +@@ -46,7 +46,7 @@ import { + } from '../../editor/index'; + import {SplitResizerHandler} from './split-resizer-handler.service'; -const INTRODUCTION_LABEL = 'Introduction'; +const INTRODUCTION_LABEL = 'イントロダクション';