From 2301e46ef5c6887639155d15fb529074568e79be Mon Sep 17 00:00:00 2001 From: Suguru Inatomi Date: Wed, 10 Sep 2025 15:31:41 +0900 Subject: [PATCH] feat: translate signals tutorial --- .../tutorials/signals/intro/README.en.md | 13 ++ .../content/tutorials/signals/intro/README.md | 14 +- .../tutorials/signals/intro/config.en.json | 6 + .../tutorials/signals/intro/config.json | 2 +- .../1-creating-your-first-signal/README.en.md | 130 ++++++++++++++++++ .../1-creating-your-first-signal/README.md | 64 ++++----- .../config.en.json | 5 + .../1-creating-your-first-signal/config.json | 2 +- .../README.en.md | 110 +++++++++++++++ .../README.md | 56 ++++---- .../config.en.json | 5 + .../config.json | 2 +- .../signals/steps/11-next-steps/README.en.md | 12 ++ .../signals/steps/11-next-steps/README.md | 12 +- .../steps/11-next-steps/config.en.json | 3 + .../signals/steps/11-next-steps/config.json | 2 +- .../README.en.md | 109 +++++++++++++++ .../README.md | 56 ++++---- .../config.en.json | 5 + .../config.json | 2 +- .../README.en.md | 95 +++++++++++++ .../README.md | 52 +++---- .../config.en.json | 5 + .../config.json | 2 +- .../README.en.md | 110 +++++++++++++++ .../README.md | 58 ++++---- .../config.en.json | 5 + .../config.json | 2 +- .../README.en.md | 105 ++++++++++++++ .../README.md | 44 +++--- .../config.en.json | 10 ++ .../config.json | 2 +- .../README.en.md | 128 +++++++++++++++++ .../README.md | 72 +++++----- .../config.en.json | 5 + .../config.json | 2 +- .../README.en.md | 103 ++++++++++++++ .../7-using-signals-with-services/README.md | 34 ++--- .../config.en.json | 11 ++ .../7-using-signals-with-services/config.json | 2 +- .../README.en.md | 110 +++++++++++++++ .../8-using-signals-with-directives/README.md | 34 ++--- .../config.en.json | 5 + .../config.json | 2 +- .../README.en.md | 66 +++++++++ .../README.md | 34 ++--- .../config.en.json | 10 ++ .../config.json | 2 +- 48 files changed, 1443 insertions(+), 277 deletions(-) create mode 100644 adev-ja/src/content/tutorials/signals/intro/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/intro/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/11-next-steps/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/11-next-steps/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/config.en.json create mode 100644 adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.en.md create mode 100644 adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/config.en.json diff --git a/adev-ja/src/content/tutorials/signals/intro/README.en.md b/adev-ja/src/content/tutorials/signals/intro/README.en.md new file mode 100644 index 0000000000..b9d8df86d9 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/intro/README.en.md @@ -0,0 +1,13 @@ +# Learn Angular signals + +This interactive tutorial will teach you the fundamentals of Angular signals and how to use them to build reactive applications. + +## How to use this tutorial + +This tutorial assumes you understand Angular's core concepts. If you're new to Angular, read our [essentials guide](/essentials). + +Each step represents a concept in Angular signals. You can do one, or all of them. + +If you get stuck, click "Reveal answer" at the top. + +Alright, let's [get started](/tutorials/signals/1-creating-your-first-signal)! diff --git a/adev-ja/src/content/tutorials/signals/intro/README.md b/adev-ja/src/content/tutorials/signals/intro/README.md index b9d8df86d9..96a4d52a2b 100644 --- a/adev-ja/src/content/tutorials/signals/intro/README.md +++ b/adev-ja/src/content/tutorials/signals/intro/README.md @@ -1,13 +1,13 @@ -# Learn Angular signals +# Angularシグナルを学ぶ -This interactive tutorial will teach you the fundamentals of Angular signals and how to use them to build reactive applications. +このインタラクティブなチュートリアルでは、Angularシグナルの基礎と、それらを使用してリアクティブなアプリケーションを構築する方法を学びます。 -## How to use this tutorial +## このチュートリアルの使い方 {#how-to-use-this-tutorial} -This tutorial assumes you understand Angular's core concepts. If you're new to Angular, read our [essentials guide](/essentials). +このチュートリアルは、Angularのコアコンセプトを理解していることを前提としています。Angularを初めて使用する場合は、[基本ガイド](/essentials)をお読みください。 -Each step represents a concept in Angular signals. You can do one, or all of them. +各ステップは、Angular signalsのコンセプトを表しています。1つだけ実行することも、すべて実行できます。 -If you get stuck, click "Reveal answer" at the top. +行き詰まった場合は、上部にある「Reveal answer」をクリックしてください。 -Alright, let's [get started](/tutorials/signals/1-creating-your-first-signal)! +さあ、[始めましょう](/tutorials/signals/1-creating-your-first-signal)! diff --git a/adev-ja/src/content/tutorials/signals/intro/config.en.json b/adev-ja/src/content/tutorials/signals/intro/config.en.json new file mode 100644 index 0000000000..6b50b1f91a --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/intro/config.en.json @@ -0,0 +1,6 @@ +{ + "title": "Learn Angular signals", + "type": "editor", + "nextTutorial": "first-app", + "openFiles": ["src/app/app.ts", "src/app/app.html", "src/app/app.css"] +} \ No newline at end of file diff --git a/adev-ja/src/content/tutorials/signals/intro/config.json b/adev-ja/src/content/tutorials/signals/intro/config.json index 96f13323e6..2249a20ddb 100644 --- a/adev-ja/src/content/tutorials/signals/intro/config.json +++ b/adev-ja/src/content/tutorials/signals/intro/config.json @@ -1,5 +1,5 @@ { - "title": "Learn Angular signals", + "title": "Angularシグナルを学ぶ", "type": "editor", "nextTutorial": "first-app", "openFiles": ["src/app/app.ts", "src/app/app.html", "src/app/app.css"] diff --git a/adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.en.md b/adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.en.md new file mode 100644 index 0000000000..cd2cf9372d --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.en.md @@ -0,0 +1,130 @@ +# Creating and updating your first signal + +Welcome to the Angular signals tutorial! [Signals](/essentials/signals) are Angular's reactive primitive that provide a way to manage state and automatically update your UI when that state changes. + +In this activity, you'll learn how to: + +- Create your first signal using the `signal()` function +- Display its value in a template +- Update the signal value using `set()` and `update()` methods + +Let's build an interactive user status system with signals! + +
+ + + + +Import the `signal` function from `@angular/core` at the top of your component file. + +```ts +import {Component, signal, ChangeDetectionStrategy} from '@angular/core'; +``` + + + + +Add a `userStatus` signal to your component class that is initialized with a value of `'offline'`. + +```ts +@Component({ + /* Config omitted */ +}) +export class App { + userStatus = signal<'online' | 'offline'>('offline'); +} +``` + + + + +Update the status indicator to display the current user status by: +1. Binding the signal to the class attribute with `[class]="userStatus()"` +2. Displaying the status text by replacing `???` with `{{ userStatus() }}` + +```html + +
+ + Status: ??? +
+ + +
+ + Status: {{ userStatus() }} +
+``` + +Notice how we call the signal `userStatus()` with parentheses to read its value. +
+ + +Add methods to your component that change the user status using the `set()` method. + +```ts +goOnline() { + this.userStatus.set('online'); +} + +goOffline() { + this.userStatus.set('offline'); +} +``` + +The `set()` method replaces the signal's value entirely with a new value. + + + + +The buttons are already in the template. Now connect them to your methods by adding: +1. Click handlers with `(click)` +2. Disabled states with `[disabled]` when already in that status + +```html + + + +``` + + + + +Add a `toggleStatus()` method that switches between online and offline using the `update()` method. + +```ts +toggleStatus() { + this.userStatus.update(current => current === 'online' ? 'offline' : 'online'); +} +``` + +The `update()` method takes a function that receives the current value and returns the new value. This is useful when you need to modify the existing value based on its current state. + + + + +The toggle button is already in the template. Connect it to your `toggleStatus()` method: + +```html + +``` + + + +
+ +Congratulations! You've created your first signal and learned how to update it using both `set()` and `update()` methods. The `signal()` function creates a reactive value that Angular tracks, and when you update it, your UI automatically reflects the changes. + +Next, you'll learn [how to derive state from signals using computed](/tutorials/signals/2-deriving-state-with-computed-signals)! + + + +You might notice `ChangeDetectionStrategy.OnPush` in the component decorator throughout this tutorial. This is a performance optimization for Angular components that use signals. For now, you can safely ignore it—just know it helps your app run faster when using signals! You can learn more in the [change detection strategies API docs](/api/core/ChangeDetectionStrategy). + + diff --git a/adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.md b/adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.md index cd2cf9372d..e9c938a3e8 100644 --- a/adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.md +++ b/adev-ja/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.md @@ -1,21 +1,21 @@ -# Creating and updating your first signal +# 初めてのシグナルの作成と更新 -Welcome to the Angular signals tutorial! [Signals](/essentials/signals) are Angular's reactive primitive that provide a way to manage state and automatically update your UI when that state changes. +Angularシグナルチュートリアルへようこそ![シグナル](/essentials/signals)は、状態を管理し、その状態が変化したときにUIを自動的に更新する方法を提供するAngularのリアクティブプリミティブです。 -In this activity, you'll learn how to: +このアクティビティでは、以下の方法を学びます。 -- Create your first signal using the `signal()` function -- Display its value in a template -- Update the signal value using `set()` and `update()` methods +- `signal()`関数を使用して初めてのシグナルを作成する +- テンプレートでその値を表示する +- `set()`および`update()`メソッドを使用してシグナル値を更新する -Let's build an interactive user status system with signals! +シグナルを使ってインタラクティブなユーザー状態システムを構築しましょう!
- -Import the `signal` function from `@angular/core` at the top of your component file. + +コンポーネントファイルの先頭で、`@angular/core`から`signal`関数をインポートします。 ```ts import {Component, signal, ChangeDetectionStrategy} from '@angular/core'; @@ -23,8 +23,8 @@ import {Component, signal, ChangeDetectionStrategy} from '@angular/core'; - -Add a `userStatus` signal to your component class that is initialized with a value of `'offline'`. + +コンポーネントクラスに、`'offline'`の値で初期化される`userStatus`シグナルを追加します。 ```ts @Component({ @@ -37,10 +37,10 @@ export class App { - -Update the status indicator to display the current user status by: -1. Binding the signal to the class attribute with `[class]="userStatus()"` -2. Displaying the status text by replacing `???` with `{{ userStatus() }}` + +現在のユーザー状態を表示するようにステータスインジケーターを更新します。 +1. `[class]="userStatus()"`を使用してシグナルをclass属性にバインドする +2. `???`を`{{ userStatus() }}`に置き換えてステータステキストを表示する ```html @@ -56,11 +56,11 @@ Update the status indicator to display the current user status by: ``` -Notice how we call the signal `userStatus()` with parentheses to read its value. +シグナル`userStatus()`を括弧付きで呼び出してその値を読み取る方法に注目してください。 - -Add methods to your component that change the user status using the `set()` method. + +コンポーネントに、`set()`メソッドを使用してユーザー状態を変更するメソッドを追加します。 ```ts goOnline() { @@ -72,14 +72,14 @@ goOffline() { } ``` -The `set()` method replaces the signal's value entirely with a new value. +`set()`メソッドは、シグナルの値を新しい値で完全に置き換えます。 - -The buttons are already in the template. Now connect them to your methods by adding: -1. Click handlers with `(click)` -2. Disabled states with `[disabled]` when already in that status + +ボタンはすでにテンプレートにあります。次に、以下を追加してメソッドに接続します。 +1. `(click)`によるクリックハンドラー +2. すでにその状態である場合の`[disabled]`による無効状態 ```html @@ -93,8 +93,8 @@ The buttons are already in the template. Now connect them to your methods by add - -Add a `toggleStatus()` method that switches between online and offline using the `update()` method. + +オンラインとオフラインを切り替える`toggleStatus()`メソッドを`update()`メソッドを使用して追加します。 ```ts toggleStatus() { @@ -102,12 +102,12 @@ toggleStatus() { } ``` -The `update()` method takes a function that receives the current value and returns the new value. This is useful when you need to modify the existing value based on its current state. +`update()`メソッドは、現在の値を受け取り、新しい値を返す関数を取ります。これは、現在の状態に基づいて既存の値を変更する必要がある場合に便利です。 - -The toggle button is already in the template. Connect it to your `toggleStatus()` method: + +トグルボタンはすでにテンプレートにあります。それを`toggleStatus()`メソッドに接続します。 ```html + + + +``` + + + + +Now test the behavior: + +1. Change the user status - notice how `notificationsEnabled` updates automatically +2. Manually toggle notifications - it overrides the computed value +3. Change status again - the linked signal re-syncs with its computation + +This demonstrates that linked signals maintain their reactive connection even after being manually set! + + + + +Excellent! You've learned the key differences between computed and linked signals: + +- **Computed signals**: Read-only, always derived from other signals +- **Linked signals**: Writable, can be both derived AND manually updated +- **Use computed when**: The value should always be calculated +- **Use linkedSignal when**: You need a default computation that can be overridden + +In the next lesson, you'll learn [how to manage async data with signals](/tutorials/signals/4-managing-async-data-with-signals)! diff --git a/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.md b/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.md index 5623d00ed3..d8ac61cbd8 100644 --- a/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.md +++ b/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.md @@ -1,17 +1,17 @@ -# Deriving state with linked signals +# リンクシグナルによる状態の派生 -Now that you've learned [how to derive state with computed signals](/tutorials/signals/2-deriving-state-with-computed-signals), you created a computed signal for `notificationsEnabled` that automatically followed your user status. But what if users want to manually disable notifications even when they're online? That's where linked signals come in. +[算出シグナルによる状態の派生方法](/tutorials/signals/2-deriving-state-with-computed-signals)を学んだ今、ユーザーのステータスに自動的に追従する`notificationsEnabled`の算出シグナルを作成しました。しかし、ユーザーがオンラインであっても手動で通知を無効にしたい場合はどうでしょうか?そこでリンクシグナルの出番です。 -Linked signals are writable signals that maintain a reactive connection to their source signals. They're perfect for creating state that normally follows a computation but can be overridden when needed. +リンクシグナルは、ソースシグナルとのリアクティブな接続を維持する書き込み可能なシグナルです。通常は計算に従うが、必要に応じて上書きできる状態を作成するのに最適です。 -In this activity, you'll learn how `linkedSignal()` differs from `computed()` by enhancing the previous user status system's computed `notificationsEnabled` to a writable linked signal. +この演習では、以前のユーザーの状態システムの算出シグナル`notificationsEnabled`を書き込み可能なリンクシグナルに拡張することで、`linkedSignal()`が`computed()`とどのように異なるかを学びます。
- -Add `linkedSignal` to your existing imports. + +既存のインポートに`linkedSignal`を追加します。 ```ts // Add linkedSignal to existing imports @@ -20,8 +20,8 @@ import {Component, signal, computed, linkedSignal, ChangeDetectionStrategy} from - -Replace the computed `notificationsEnabled` with a linkedSignal using the exact same expression: + +算出シグナル`notificationsEnabled`を、まったく同じ式を使用してリンクシグナルに置き換えます。 ```ts // Previously (from lesson 2): @@ -31,11 +31,11 @@ Replace the computed `notificationsEnabled` with a linkedSignal using the exact notificationsEnabled = linkedSignal(() => this.userStatus() === 'online'); ``` -The expression is identical, but linkedSignal creates a writable signal. It will still automatically update when `userStatus` changes, but you can also set it manually. +式は同じですが、linkedSignalは書き込み可能なシグナルを作成します。`userStatus`が変更されると自動的に更新されますが、手動で設定できます。 - -Add a method to demonstrate that linked signals can be written to directly: + +リンクシグナルに直接書き込むことができることを示すメソッドを追加します。 ```ts toggleNotifications() { @@ -44,11 +44,11 @@ toggleNotifications() { } ``` -This is the key difference: computed signals are read-only, but linked signals can be updated manually while still maintaining their reactive connection. +これが主な違いです。算出シグナルは読み取り専用ですが、リンクシグナルはリアクティブな接続を維持しながら手動で更新できます。 - -Update your template to add a toggle button for notifications: + +テンプレートを更新して、通知用のトグルボタンを追加します。 ```html
@@ -73,23 +73,23 @@ Update your template to add a toggle button for notifications: - -Now test the behavior: + +次に、動作をテストします。 -1. Change the user status - notice how `notificationsEnabled` updates automatically -2. Manually toggle notifications - it overrides the computed value -3. Change status again - the linked signal re-syncs with its computation +1. ユーザーの状態を変更します。`notificationsEnabled`が自動的に更新されることに注目してください。 +2. 通知を手動で切り替えます。算出された値を上書きします。 +3. 再度ステータスを変更します。リンクシグナルは計算と再同期します。 -This demonstrates that linked signals maintain their reactive connection even after being manually set! +これは、リンクシグナルが手動で設定された後でもリアクティブな接続を維持することを示しています! -Excellent! You've learned the key differences between computed and linked signals: +素晴らしい!算出シグナルとリンクシグナルの主な違いを学びました。 -- **Computed signals**: Read-only, always derived from other signals -- **Linked signals**: Writable, can be both derived AND manually updated -- **Use computed when**: The value should always be calculated -- **Use linkedSignal when**: You need a default computation that can be overridden +- **算出シグナル**: 読み取り専用で、常に他のシグナルから派生します +- **リンクシグナル**: 書き込み可能で、派生と手動更新の両方が可能です +- **算出シグナルを使用する場合**: 値が常に計算されるべきとき +- **リンクシグナルを使用する場合**: 上書き可能なデフォルトの計算が必要なとき -In the next lesson, you'll learn [how to manage async data with signals](/tutorials/signals/4-managing-async-data-with-signals)! +次のレッスンでは、[シグナルで非同期データを管理する方法](/tutorials/signals/4-managing-async-data-with-signals)を学びます! diff --git a/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/config.en.json b/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/config.en.json new file mode 100644 index 0000000000..5aae6e53e2 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/config.en.json @@ -0,0 +1,5 @@ +{ + "openFiles": ["src/app/app.ts", "src/app/app.css"], + "type": "editor", + "title": "Deriving state with linked signals" +} \ No newline at end of file diff --git a/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/config.json b/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/config.json index a8332116ec..ae9411ecf6 100644 --- a/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/config.json +++ b/adev-ja/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/config.json @@ -1,5 +1,5 @@ { "openFiles": ["src/app/app.ts", "src/app/app.css"], "type": "editor", - "title": "Deriving state with linked signals" + "title": "リンクシグナルで状態を派生させる" } diff --git a/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.en.md b/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.en.md new file mode 100644 index 0000000000..93a79e4e66 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.en.md @@ -0,0 +1,110 @@ +# Managing async data with signals using the Resources API + +Now that you've learned [how to derive state with linked signals](/tutorials/signals/3-deriving-state-with-linked-signals), let's explore how to handle asynchronous data with the Resource API. The Resource API provides a powerful way to manage async operations using signals, with built-in loading states, error handling, and request management. + +In this activity, you'll learn how to use the `resource()` function to load data asynchronously and how to handle different states of async operations by building a user profile loader that demonstrates the Resource API in action. + +
+ + + + +Add `resource` to your existing imports and import the fake API function. + +```ts +// Add resource to existing imports +import {Component, signal, computed, resource, ChangeDetectionStrategy} from '@angular/core'; +// Import mock API function +import {loadUser} from './user-api'; +``` + + + + +Add a property in the component class that creates a resource to load user data based on a user ID signal. + +```ts +userId = signal(1); + +userResource = resource({ + params: () => ({ id: this.userId() }), + loader: (params) => loadUser(params.params.id) +}); +``` + + + + +Add methods to change the user ID and reload the resource. + +```ts +loadUser(id: number) { + this.userId.set(id); +} + +reloadUser() { + this.userResource.reload(); +} +``` + +Changing the params signal automatically triggers a reload, or you can manually reload with `reload()`. + + + +Add computed signals to access different states of the resource. + +```ts +isLoading = computed(() => this.userResource.status() === 'loading'); +hasError = computed(() => this.userResource.status() === 'error'); +``` + +Resources provide a `status()` signal that can be 'loading', 'success', or 'error', a `value()` signal for the loaded data, and a `hasValue()` method that safely checks if data is available. + + + +The template structure is already provided. Now connect everything: + +Part 1. **Add click handlers to the buttons:** + +```html + + + + +``` + +Part 2. **Replace the placeholder with resource state handling:** + +```html +@if (isLoading()) { +

Loading user...

+} @else if (hasError()) { +

Error: {{ userResource.error()?.message }}

+} @else if (userResource.hasValue()) { + +} +``` + +The resource provides different methods to check its state: + +- `isLoading()` - true when fetching data +- `hasError()` - true when an error occurred +- `userResource.hasValue()` - true when data is available +- `userResource.value()` - access the loaded data +- `userResource.error()` - access error information + +
+ +
+ +Excellent! You've now learned how to use the Resource API with signals. Key concepts to remember: + +- **Resources are reactive**: They automatically reload when params change +- **Built-in state management**: Resources provide `status()`, `value()`, and `error()` signals +- **Automatic cleanup**: Resources handle request cancellation and cleanup automatically +- **Manual control**: You can manually reload or abort requests when needed + +In the next lesson, you'll learn [how to pass data to components with input signals](/tutorials/signals/5-component-communication-with-signals)! diff --git a/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md b/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md index 93a79e4e66..841a77406c 100644 --- a/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md +++ b/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md @@ -1,15 +1,15 @@ -# Managing async data with signals using the Resources API +# Resources APIでシグナルを使った非同期データの管理 -Now that you've learned [how to derive state with linked signals](/tutorials/signals/3-deriving-state-with-linked-signals), let's explore how to handle asynchronous data with the Resource API. The Resource API provides a powerful way to manage async operations using signals, with built-in loading states, error handling, and request management. +[リンクされたシグナルで状態を派生させる方法](/tutorials/signals/3-deriving-state-with-linked-signals)を学んだところで、Resource APIを使って非同期データを処理する方法を探ってみましょう。Resource APIは、組み込みのローディング状態、エラー処理、リクエスト管理を備え、シグナルを使って非同期操作を管理する強力な方法を提供します。 -In this activity, you'll learn how to use the `resource()` function to load data asynchronously and how to handle different states of async operations by building a user profile loader that demonstrates the Resource API in action. +このアクティビティでは、`resource()`関数を使ってデータを非同期にロードする方法と、Resource APIの動作を示すユーザープロファイルローダーを構築することで、非同期操作のさまざまな状態を処理する方法を学びます。
- -Add `resource` to your existing imports and import the fake API function. + +既存のインポートに`resource`を追加し、フェイクAPI関数をインポートします。 ```ts // Add resource to existing imports @@ -20,8 +20,8 @@ import {loadUser} from './user-api'; - -Add a property in the component class that creates a resource to load user data based on a user ID signal. + +ユーザーIDシグナルに基づいてユーザーデータをロードするリソースを作成するプロパティをコンポーネントクラスに追加します。 ```ts userId = signal(1); @@ -34,8 +34,8 @@ userResource = resource({ - -Add methods to change the user ID and reload the resource. + +ユーザーIDを変更し、リソースをリロードするメソッドを追加します。 ```ts loadUser(id: number) { @@ -47,24 +47,24 @@ reloadUser() { } ``` -Changing the params signal automatically triggers a reload, or you can manually reload with `reload()`. +paramsシグナルを変更すると自動的にリロードがトリガーされます。または、`reload()`を使って手動でリロードできます。 - -Add computed signals to access different states of the resource. + +リソースの異なる状態にアクセスするための算出シグナルを追加します。 ```ts isLoading = computed(() => this.userResource.status() === 'loading'); hasError = computed(() => this.userResource.status() === 'error'); ``` -Resources provide a `status()` signal that can be 'loading', 'success', or 'error', a `value()` signal for the loaded data, and a `hasValue()` method that safely checks if data is available. +リソースは、'loading'、'success'、または'error'になり得る`status()`シグナル、ロードされたデータ用の`value()`シグナル、そしてデータが利用可能かどうかを安全にチェックする`hasValue()`メソッドを提供します。 - -The template structure is already provided. Now connect everything: + +テンプレート構造はすでに提供されています。すべてを接続しましょう。 -Part 1. **Add click handlers to the buttons:** +Part 1. **ボタンにクリックハンドラーを追加します。** ```html @@ -73,7 +73,7 @@ Part 1. **Add click handlers to the buttons:** ``` -Part 2. **Replace the placeholder with resource state handling:** +Part 2. **プレースホルダーをリソースの状態処理に置き換えます。** ```html @if (isLoading()) { @@ -88,23 +88,23 @@ Part 2. **Replace the placeholder with resource state handling:** } ``` -The resource provides different methods to check its state: +リソースは、その状態をチェックするためのさまざまなメソッドを提供します。 -- `isLoading()` - true when fetching data -- `hasError()` - true when an error occurred -- `userResource.hasValue()` - true when data is available -- `userResource.value()` - access the loaded data -- `userResource.error()` - access error information +- `isLoading()` - データフェッチ中にtrue +- `hasError()` - エラー発生時にtrue +- `userResource.hasValue()` - データが利用可能な場合にtrue +- `userResource.value()` - ロードされたデータにアクセス +- `userResource.error()` - エラー情報にアクセス -Excellent! You've now learned how to use the Resource API with signals. Key concepts to remember: +素晴らしい!これでResource APIをシグナルと組み合わせて使う方法を学びました。覚えておくべき重要な概念は次のとおりです。 -- **Resources are reactive**: They automatically reload when params change -- **Built-in state management**: Resources provide `status()`, `value()`, and `error()` signals -- **Automatic cleanup**: Resources handle request cancellation and cleanup automatically -- **Manual control**: You can manually reload or abort requests when needed +- **リソースはリアクティブです**: パラメータが変更されると自動的にリロードされます +- **組み込みの状態管理**: リソースは`status()`、`value()`、`error()`シグナルを提供します +- **自動クリーンアップ**: リソースはリクエストのキャンセルとクリーンアップを自動的に処理します +- **手動制御**: 必要に応じて手動でリロードしたり、リクエストを中止したりできます -In the next lesson, you'll learn [how to pass data to components with input signals](/tutorials/signals/5-component-communication-with-signals)! +次のレッスンでは、[入力シグナルでコンポーネントにデータを渡す方法](/tutorials/signals/5-component-communication-with-signals)を学びます! diff --git a/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/config.en.json b/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/config.en.json new file mode 100644 index 0000000000..66a3049ebe --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/config.en.json @@ -0,0 +1,5 @@ +{ + "openFiles": ["src/app/app.ts", "src/app/user-api.ts", "src/app/app.css"], + "type": "editor", + "title": "Managing async data with signals using the Resources API" +} \ No newline at end of file diff --git a/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/config.json b/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/config.json index 48bac02bb9..dc8b35bdd3 100644 --- a/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/config.json +++ b/adev-ja/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/config.json @@ -1,5 +1,5 @@ { "openFiles": ["src/app/app.ts", "src/app/user-api.ts", "src/app/app.css"], "type": "editor", - "title": "Managing async data with signals using the Resources API" + "title": "Resources APIでシグナルを使った非同期データの管理" } diff --git a/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.en.md b/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.en.md new file mode 100644 index 0000000000..528af3b1b3 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.en.md @@ -0,0 +1,105 @@ +# Passing data to components with input signals + +Now that you've learned [managing async data with signals](/tutorials/signals/4-managing-async-data-with-signals), let's explore Angular's signal-based `input()` API for passing data from parent to child components, making component data flow more reactive and efficient. If you're familiar with component props from other frameworks, inputs are the same idea. + +In this activity, you'll add signal inputs to a product card component and see how parent data flows down reactively. + +
+ + + + +Add signal `input()` functions to receive data in the `product-card` component. + +```ts +// Add imports for signal inputs +import {Component, input} from '@angular/core'; + +// Add these signal inputs +name = input.required(); +price = input.required(); +available = input(true); +``` + +Notice how `input.required()` creates an input that must be provided, while `input()` with a default value is optional. + + + +Update the template in `product-card` to display the signal input values. + +```html +
+

{{ name() }}

+

\${{ price() }}

+

Status: + @if (available()) { + Available + } @else { + Out of Stock + } +

+
+``` + +Input signals work just like regular signals in templates - call them as functions to access their values. +
+ + +Update the `product-card` usage in `app.ts` to pass dynamic signal values instead of static ones. + +```html + + + + + +``` + +The square brackets `[]` create property bindings that pass the current signal values to the child. + + + +Add methods in `app.ts` to update the parent signals and see how the child component reacts automatically. + +```ts +updateProduct() { + this.productName.set('Updated Product'); + this.productPrice.set(149); +} + +toggleAvailability() { + this.productAvailable.set(!this.productAvailable()); +} +``` + +```html + +
+ + +
+``` + +When parent signals change, the child component automatically receives and displays the new values! +
+ +
+ +Excellent! You've learned how signal inputs work: + +- **Signal inputs** - Use `input()` and `input.required()` to receive data from parent components +- **Reactive updates** - Child components automatically update when parent signal values change +- **Type safety** - Signal inputs provide full TypeScript type checking +- **Default values** - Optional inputs can have default values while required inputs must be provided + +Signal inputs make component communication more reactive and eliminate the need for `OnChanges` lifecycle hooks in many cases. + +In the next lesson, you'll learn about [two-way binding with model signals](/tutorials/signals/6-two-way-binding-with-model-signals)! diff --git a/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.md b/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.md index 528af3b1b3..7e17c53ebd 100644 --- a/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.md +++ b/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.md @@ -1,15 +1,15 @@ -# Passing data to components with input signals +# コンポーネントに入力シグナルでデータを渡す -Now that you've learned [managing async data with signals](/tutorials/signals/4-managing-async-data-with-signals), let's explore Angular's signal-based `input()` API for passing data from parent to child components, making component data flow more reactive and efficient. If you're familiar with component props from other frameworks, inputs are the same idea. +[シグナルで非同期データを管理する](/tutorials/signals/4-managing-async-data-with-signals)方法を学んだところで、親から子コンポーネントへデータを渡すためのAngularのシグナルベースの`input()` APIを探求し、コンポーネントのデータフローをよりリアクティブで効率的にしましょう。他のフレームワークのコンポーネントプロパティに慣れているなら、入力も同じ考え方です。 -In this activity, you'll add signal inputs to a product card component and see how parent data flows down reactively. +このアクティビティでは、プロダクトカードコンポーネントにシグナル入力を追加し、親データがどのようにリアクティブに流れていくかを確認します。
- -Add signal `input()` functions to receive data in the `product-card` component. + +`product-card`コンポーネントでデータを受け取るために、シグナル`input()`関数を追加します。 ```ts // Add imports for signal inputs @@ -21,11 +21,11 @@ price = input.required(); available = input(true); ``` -Notice how `input.required()` creates an input that must be provided, while `input()` with a default value is optional. +`input.required()`が必須の入力を作成するのに対し、デフォルト値を持つ`input()`はオプションであることに注目してください。 - -Update the template in `product-card` to display the signal input values. + +`product-card`のテンプレートを更新して、シグナル入力値を表示します。 ```html
@@ -41,11 +41,11 @@ Update the template in `product-card` to display the signal input values.
``` -Input signals work just like regular signals in templates - call them as functions to access their values. +入力シグナルは、テンプレート内で通常のシグナルと同じように機能します。関数として呼び出して値にアクセスします。
- -Update the `product-card` usage in `app.ts` to pass dynamic signal values instead of static ones. + +`app.ts`内の`product-card`の使用箇所を更新し、静的な値の代わりに動的なシグナル値を渡すようにします。 ```html @@ -63,11 +63,11 @@ Update the `product-card` usage in `app.ts` to pass dynamic signal values instea /> ``` -The square brackets `[]` create property bindings that pass the current signal values to the child. +角括弧`[]`は、現在のシグナル値を子に渡すプロパティバインディングを作成します。 - -Add methods in `app.ts` to update the parent signals and see how the child component reacts automatically. + +`app.ts`にメソッドを追加して親シグナルを更新し、子コンポーネントがどのように自動的に反応するかを確認します。 ```ts updateProduct() { @@ -88,18 +88,18 @@ toggleAvailability() {
``` -When parent signals change, the child component automatically receives and displays the new values! +親シグナルが変更されると、子コンポーネントは自動的に新しい値を受け取り、表示します!
-Excellent! You've learned how signal inputs work: +素晴らしい!シグナル入力の仕組みを学びました。 -- **Signal inputs** - Use `input()` and `input.required()` to receive data from parent components -- **Reactive updates** - Child components automatically update when parent signal values change -- **Type safety** - Signal inputs provide full TypeScript type checking -- **Default values** - Optional inputs can have default values while required inputs must be provided +- **シグナル入力** - 親コンポーネントからデータを受け取るために`input()`と`input.required()`を使用します +- **リアクティブな更新** - 親シグナル値が変更されると、子コンポーネントは自動的に更新されます +- **型安全性** - シグナル入力は完全なTypeScriptの型チェックを提供します +- **デフォルト値** - オプションの入力はデフォルト値を持つことができ、必須の入力は提供されなければなりません -Signal inputs make component communication more reactive and eliminate the need for `OnChanges` lifecycle hooks in many cases. +シグナル入力はコンポーネント間の通信をよりリアクティブにし、多くの場合で`OnChanges`ライフサイクルフックの必要性を排除します。 -In the next lesson, you'll learn about [two-way binding with model signals](/tutorials/signals/6-two-way-binding-with-model-signals)! +次のレッスンでは、[モデルシグナルによる双方向バインディング](/tutorials/signals/6-two-way-binding-with-model-signals)について学びます! diff --git a/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/config.en.json b/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/config.en.json new file mode 100644 index 0000000000..4e68e02a24 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/config.en.json @@ -0,0 +1,10 @@ +{ + "openFiles": [ + "src/app/app.ts", + "src/app/product-card.ts", + "src/app/quantity-selector.ts", + "src/app/app.css" + ], + "type": "editor", + "title": "Passing data to components with input signals" +} \ No newline at end of file diff --git a/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/config.json b/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/config.json index dffea145ef..0fa2c62775 100644 --- a/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/config.json +++ b/adev-ja/src/content/tutorials/signals/steps/5-component-communication-with-signals/config.json @@ -6,5 +6,5 @@ "src/app/app.css" ], "type": "editor", - "title": "Passing data to components with input signals" + "title": "コンポーネントに入力シグナルでデータを渡す" } diff --git a/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.en.md b/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.en.md new file mode 100644 index 0000000000..d68cdee85f --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.en.md @@ -0,0 +1,128 @@ +# Two-way binding with model signals + +Now that you've learned [passing data to components with input signals](/tutorials/signals/5-component-communication-with-signals), let's explore Angular's `model()` API for two-way binding. Model signals are perfect for UI components like checkboxes, sliders, or custom form controls where the component needs to both receive a value AND update it. + +In this activity, you'll create a custom checkbox component that manages its own state while keeping the parent synchronized. + +
+ + + + +Create a model signal in the `custom-checkbox` component that can both receive and update the parent's value. + +```ts +// Add imports for model signals +import {Component, model, input} from '@angular/core'; + +// Model signal for two-way binding +checked = model.required(); + +// Optional input for label +label = input(''); +``` + +Unlike `input()` signals which are read-only, `model()` signals can be both read and written to. + + + +Build the checkbox template that responds to clicks and updates its own model. + +```html + +``` + +The component reads from its model signal and has a method to update it. + + + +Implement the toggle method that updates the model signal when the checkbox is clicked. + +```ts +toggle() { + // This updates BOTH the component's state AND the parent's model! + this.checked.set(!this.checked()); +} +``` + +When the child component calls `this.checked.set()`, it automatically propagates the change back to the parent. This is the key difference from `input()` signals. + + + +First, uncomment the model signal properties and methods in `app.ts`: + +```ts +// Parent signal models +agreedToTerms = model(false); +enableNotifications = model(true); + +// Methods to test two-way binding +toggleTermsFromParent() { + this.agreedToTerms.set(!this.agreedToTerms()); +} + +resetAll() { + this.agreedToTerms.set(false); + this.enableNotifications.set(false); +} +``` + +Then update the template: + +Part 1. **Uncomment the checkboxes and add two-way binding:** + +- Replace `___ADD_TWO_WAY_BINDING___` with `[(checked)]="agreedToTerms"` for the first checkbox +- Replace `___ADD_TWO_WAY_BINDING___` with `[(checked)]="enableNotifications"` for the second + +Part 2. **Replace the `???` placeholders with @if blocks:** + +```html +@if (agreedToTerms()) { + Yes +} @else { + No +} +``` + +Part 3. **Add click handlers to the buttons:** + +```html + + +``` + +The `[(checked)]` syntax creates two-way binding - data flows down to the component AND changes flow back up to the parent by emitting an event that references the signal itself and does _not_ call the signal getter directly. + + + +Interact with your app to see two-way binding in action: + +1. **Click checkboxes** - Component updates its own state and notifies parent +2. **Click "Toggle Terms from Parent"** - Parent updates propagate down to component +3. **Click "Reset All"** - Parent resets both models and components update automatically + +Both the parent and child can update the shared state, and both stay in sync automatically! + + + + +Perfect! You've learned how model signals enable two-way binding: + +- **Model signals** - Use `model()` and `model.required()` for values that can be both read and written +- **Two-way binding** - Use `[(property)]` syntax to bind parent signals to child models +- **Perfect for UI components** - Checkboxes, form controls, and widgets that need to manage their own state +- **Automatic synchronization** - Parent and child stay in sync without manual event handling + +**When to use `model()` vs `input()`:** + +- Use `input()` for data that only flows down (display data, configuration) +- Use `model()` for UI components that need to update their own value (form controls, toggles) + +In the next lesson, you'll learn about [using signals with services](/tutorials/signals/7-using-signals-with-services)! diff --git a/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.md b/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.md index d68cdee85f..fd548721f2 100644 --- a/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.md +++ b/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.md @@ -1,15 +1,15 @@ -# Two-way binding with model signals +# modelシグナルによる双方向バインディング -Now that you've learned [passing data to components with input signals](/tutorials/signals/5-component-communication-with-signals), let's explore Angular's `model()` API for two-way binding. Model signals are perfect for UI components like checkboxes, sliders, or custom form controls where the component needs to both receive a value AND update it. +[inputシグナルによるコンポーネントへのデータ受け渡し](/tutorials/signals/5-component-communication-with-signals)を学習したところで、Angularの`model()` APIを使った双方向バインディングについて見ていきましょう。modelシグナルは、チェックボックス、スライダー、カスタムフォームコントロールなど、コンポーネントが値を受け取ると同時に更新する必要があるUIコンポーネントに最適です。 -In this activity, you'll create a custom checkbox component that manages its own state while keeping the parent synchronized. +このアクティビティでは、親と同期を保ちながら自身の状態を管理するカスタムチェックボックスコンポーネントを作成します。
- -Create a model signal in the `custom-checkbox` component that can both receive and update the parent's value. + +`custom-checkbox`コンポーネントに、親の値を送受信できるmodelシグナルを作成します。 ```ts // Add imports for model signals @@ -22,11 +22,11 @@ checked = model.required(); label = input(''); ``` -Unlike `input()` signals which are read-only, `model()` signals can be both read and written to. +読み取り専用の`input()`シグナルとは異なり、`model()`シグナルは読み取りと書き込みの両方が可能です。 - -Build the checkbox template that responds to clicks and updates its own model. + +クリックに応答し、自身のモデルを更新するチェックボックスのテンプレートを作成します。 ```html ``` -The component reads from its model signal and has a method to update it. +コンポーネントはmodelシグナルから読み取り、それを更新するメソッドを持っています。 - -Implement the toggle method that updates the model signal when the checkbox is clicked. + +チェックボックスがクリックされたときにmodelシグナルを更新するtoggleメソッドを実装します。 ```ts toggle() { @@ -52,11 +52,11 @@ toggle() { } ``` -When the child component calls `this.checked.set()`, it automatically propagates the change back to the parent. This is the key difference from `input()` signals. +子コンポーネントが`this.checked.set()`を呼び出すと、変更は自動的に親に伝播されます。これが`input()`シグナルとの主な違いです。 - -First, uncomment the model signal properties and methods in `app.ts`: + +まず、`app.ts`内のmodelシグナルプロパティとメソッドのコメントを解除します。 ```ts // Parent signal models @@ -74,14 +74,14 @@ resetAll() { } ``` -Then update the template: +次に、テンプレートを更新します。 -Part 1. **Uncomment the checkboxes and add two-way binding:** +パート1. **チェックボックスのコメントを解除し、双方向バインディングを追加します。** -- Replace `___ADD_TWO_WAY_BINDING___` with `[(checked)]="agreedToTerms"` for the first checkbox -- Replace `___ADD_TWO_WAY_BINDING___` with `[(checked)]="enableNotifications"` for the second +- 最初のチェックボックスの`___ADD_TWO_WAY_BINDING___`を`[(checked)]="agreedToTerms"`に置き換えます。 +- 2番目のチェックボックスの`___ADD_TWO_WAY_BINDING___`を`[(checked)]="enableNotifications"`に置き換えます。 -Part 2. **Replace the `???` placeholders with @if blocks:** +パート2. **`???`プレースホルダーを@ifブロックに置き換えます。** ```html @if (agreedToTerms()) { @@ -91,38 +91,38 @@ Part 2. **Replace the `???` placeholders with @if blocks:** } ``` -Part 3. **Add click handlers to the buttons:** +パート3. **ボタンにクリックハンドラーを追加します。** ```html ``` -The `[(checked)]` syntax creates two-way binding - data flows down to the component AND changes flow back up to the parent by emitting an event that references the signal itself and does _not_ call the signal getter directly. +`[(checked)]`構文は双方向バインディングを作成します。データはコンポーネントに流れ込み、変更はシグナル自体を参照するイベントを発行することで親に流れ戻ります。このとき、シグナルゲッターを直接呼び出すことは_ありません_。 - -Interact with your app to see two-way binding in action: + +アプリケーションを操作して、双方向バインディングの動作を確認します。 -1. **Click checkboxes** - Component updates its own state and notifies parent -2. **Click "Toggle Terms from Parent"** - Parent updates propagate down to component -3. **Click "Reset All"** - Parent resets both models and components update automatically +1. **チェックボックスをクリックする** - コンポーネントは自身の状態を更新し、親に通知します。 +2. **「Toggle Terms from Parent」をクリックする** - 親の更新がコンポーネントに伝播されます。 +3. **「Reset All」をクリックする** - 親が両方のモデルをリセットし、コンポーネントが自動的に更新されます。 -Both the parent and child can update the shared state, and both stay in sync automatically! +親と子の両方が共有状態を更新でき、両方とも自動的に同期を保ちます! -Perfect! You've learned how model signals enable two-way binding: +完璧です!modelシグナルがどのように双方向バインディングを可能にするかを学びました。 -- **Model signals** - Use `model()` and `model.required()` for values that can be both read and written -- **Two-way binding** - Use `[(property)]` syntax to bind parent signals to child models -- **Perfect for UI components** - Checkboxes, form controls, and widgets that need to manage their own state -- **Automatic synchronization** - Parent and child stay in sync without manual event handling +- **Modelシグナル** - 読み取りと書き込みの両方が可能な値には`model()`と`model.required()`を使用します。 +- **双方向バインディング** - 親シグナルを子モデルにバインドするには`[(property)]`構文を使用します。 +- **UIコンポーネントに最適** - チェックボックス、フォームコントロール、および自身の状態を管理する必要があるウィジェット。 +- **自動同期** - 手動のイベント処理なしで、親と子が同期を保ちます。 -**When to use `model()` vs `input()`:** +**`model()`と`input()`の使い分け:** -- Use `input()` for data that only flows down (display data, configuration) -- Use `model()` for UI components that need to update their own value (form controls, toggles) +- データが下方向にのみ流れる場合(表示データ、設定)は`input()`を使用します。 +- 自身の値を更新する必要があるUIコンポーネント(フォームコントロール、トグル)には`model()`を使用します。 -In the next lesson, you'll learn about [using signals with services](/tutorials/signals/7-using-signals-with-services)! +次のレッスンでは、[サービスでのシグナルの使用](/tutorials/signals/7-using-signals-with-services)について学びます! diff --git a/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/config.en.json b/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/config.en.json new file mode 100644 index 0000000000..7761b01829 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/config.en.json @@ -0,0 +1,5 @@ +{ + "openFiles": ["src/app/app.ts", "src/app/custom-checkbox.ts", "src/app/app.css"], + "type": "editor", + "title": "Two-way binding with model signals" +} \ No newline at end of file diff --git a/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/config.json b/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/config.json index 37e7c462da..c29fb07169 100644 --- a/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/config.json +++ b/adev-ja/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/config.json @@ -1,5 +1,5 @@ { "openFiles": ["src/app/app.ts", "src/app/custom-checkbox.ts", "src/app/app.css"], "type": "editor", - "title": "Two-way binding with model signals" + "title": "modelシグナルによる双方向バインディング" } diff --git a/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/README.en.md b/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/README.en.md new file mode 100644 index 0000000000..6d6c554126 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/README.en.md @@ -0,0 +1,103 @@ +# Using signals with services + +Now that you've learned [two-way binding with model signals](/tutorials/signals/6-two-way-binding-with-model-signals), let's explore how to use signals with Angular services. Services are perfect for sharing reactive state across multiple components, and signals make this even more powerful by providing automatic change detection and clean reactive patterns. + +In this activity, you'll learn how to create a cart store with signals that allow the cart display component to react to state changes automatically. + +
+ + + + +Add readonly and computed signals to make the cart state reactive in `cart-store.ts`. + +```ts +// Add the computed import +import {Injectable, signal, computed} from '@angular/core'; + +// Then add these signals to the class: + +// Readonly signals +readonly cartItems = this.items.asReadonly(); + +// Computed signals +readonly totalQuantity = computed(() => { + return this.items().reduce((sum, item) => sum + item.quantity, 0); +}); + +readonly totalPrice = computed(() => { + return this.items().reduce((sum, item) => sum + item.price * item.quantity, 0); +}); +``` + +These signals allow components to reactively access cart data and computed totals. The `asReadonly()` method prevents external code from modifying the cart items directly, while `computed()` creates derived state that automatically updates when the source signal changes. + + + +The cart display component in `cart-display.ts` already uses the cart store signals in its template. Complete the quantity update methods to modify cart items: + +```ts +increaseQuantity(id: string) { + const items = this.cartStore.cartItems(); + const currentItem = items.find((item) => item.id === id); + if (currentItem) { + this.cartStore.updateQuantity(id, currentItem.quantity + 1); + } +} + +decreaseQuantity(id: string) { + const items = this.cartStore.cartItems(); + const currentItem = items.find((item) => item.id === id); + if (currentItem && currentItem.quantity > 1) { + this.cartStore.updateQuantity(id, currentItem.quantity - 1); + } +} +``` + +These methods read the current cart state using `cartItems()` and update quantities through the store's methods. The UI automatically updates when the signals change! + + + +Update the main app component in `app.ts` to use the cart service and display the cart component. + +```ts +import {Component, inject} from '@angular/core'; +import {CartStore} from './cart-store'; +import {CartDisplay} from './cart-display'; + +@Component({ + selector: 'app-root', + imports: [CartDisplay], + template: ` +
+
+

Signals with Services Demo

+
+ Cart: {{ cartStore.totalQuantity() }} items (\${{ cartStore.totalPrice() }}) +
+
+ +
+ +
+
+ `, + styleUrl: './app.css', +}) +export class App { + cartStore = inject(CartStore); +} +``` + +
+ +
+ +Excellent! You've now learned how to use signals with services. Key concepts to remember: + +- **Service-level signals**: Services can use signals to manage reactive state +- **Dependency injection**: Use `inject()` to access services with signals in components +- **Computed signals in services**: Create derived state that updates automatically +- **Readonly signals**: Expose read-only versions of signals to prevent external mutations + +In the next lesson, you'll learn about [how to use signals with directives](/tutorials/signals/8-using-signals-with-directives)! diff --git a/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/README.md b/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/README.md index 6d6c554126..7e38ef0e19 100644 --- a/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/README.md +++ b/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/README.md @@ -1,15 +1,15 @@ -# Using signals with services +# サービスでシグナルを使用する -Now that you've learned [two-way binding with model signals](/tutorials/signals/6-two-way-binding-with-model-signals), let's explore how to use signals with Angular services. Services are perfect for sharing reactive state across multiple components, and signals make this even more powerful by providing automatic change detection and clean reactive patterns. +[モデルシグナルによる双方向バインディング](/tutorials/signals/6-two-way-binding-with-model-signals)を学習したので、Angularサービスでシグナルを使用する方法を見ていきましょう。サービスは複数のコンポーネント間でリアクティブな状態を共有するのに最適であり、シグナルは自動的な変更検知とクリーンなリアクティブパターンを提供することで、これをさらに強力にします。 -In this activity, you'll learn how to create a cart store with signals that allow the cart display component to react to state changes automatically. +このアクティビティでは、カート表示コンポーネントが状態の変化に自動的に反応できるように、シグナルを使用してカートストアを作成する方法を学習します。
- -Add readonly and computed signals to make the cart state reactive in `cart-store.ts`. + +`cart-store.ts`でカートの状態をリアクティブにするために、読み取り専用シグナルと計算済みシグナルを追加します。 ```ts // Add the computed import @@ -30,11 +30,11 @@ readonly totalPrice = computed(() => { }); ``` -These signals allow components to reactively access cart data and computed totals. The `asReadonly()` method prevents external code from modifying the cart items directly, while `computed()` creates derived state that automatically updates when the source signal changes. +これらのシグナルにより、コンポーネントはカートデータと計算された合計にリアクティブにアクセスできます。`asReadonly()`メソッドは外部コードがカートアイテムを直接変更するのを防ぎ、`computed()`はソースシグナルが変更されたときに自動的に更新される派生状態を作成します。 - -The cart display component in `cart-display.ts` already uses the cart store signals in its template. Complete the quantity update methods to modify cart items: + +`cart-display.ts`のカート表示コンポーネントは、すでにテンプレートでカートストアシグナルを使用しています。カートアイテムを変更するための数量更新メソッドを完成させます。 ```ts increaseQuantity(id: string) { @@ -54,11 +54,11 @@ decreaseQuantity(id: string) { } ``` -These methods read the current cart state using `cartItems()` and update quantities through the store's methods. The UI automatically updates when the signals change! +これらのメソッドは、`cartItems()`を使用して現在のカート状態を読み取り、ストアのメソッドを通じて数量を更新します。シグナルが変更されるとUIは自動的に更新されます! - -Update the main app component in `app.ts` to use the cart service and display the cart component. + +`app.ts`のメインアプリケーションコンポーネントを更新して、カートサービスを使用し、カートコンポーネントを表示します。 ```ts import {Component, inject} from '@angular/core'; @@ -93,11 +93,11 @@ export class App { -Excellent! You've now learned how to use signals with services. Key concepts to remember: +素晴らしい!サービスでシグナルを使用する方法を学びました。覚えておくべき主要な概念は次のとおりです。 -- **Service-level signals**: Services can use signals to manage reactive state -- **Dependency injection**: Use `inject()` to access services with signals in components -- **Computed signals in services**: Create derived state that updates automatically -- **Readonly signals**: Expose read-only versions of signals to prevent external mutations +- **サービスレベルシグナル**: サービスはシグナルを使用してリアクティブな状態を管理できます +- **依存性の注入**: `inject()`を使用して、コンポーネントでシグナルを持つサービスにアクセスします +- **サービス内の計算済みシグナル**: 自動的に更新される派生状態を作成します +- **読み取り専用シグナル**: 外部からの変更を防ぐために、シグナルの読み取り専用バージョンを公開します -In the next lesson, you'll learn about [how to use signals with directives](/tutorials/signals/8-using-signals-with-directives)! +次のレッスンでは、[ディレクティブでシグナルを使用する方法](/tutorials/signals/8-using-signals-with-directives)について学習します! diff --git a/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/config.en.json b/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/config.en.json new file mode 100644 index 0000000000..60bcf15683 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/config.en.json @@ -0,0 +1,11 @@ +{ + "openFiles": [ + "src/app/app.ts", + "src/app/cart-store.ts", + "src/app/cart-display.ts", + "src/app/cart-types.ts", + "src/app/app.css" + ], + "type": "editor", + "title": "Using signals with services" +} \ No newline at end of file diff --git a/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/config.json b/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/config.json index 845081b9c4..f256d1b494 100644 --- a/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/config.json +++ b/adev-ja/src/content/tutorials/signals/steps/7-using-signals-with-services/config.json @@ -7,5 +7,5 @@ "src/app/app.css" ], "type": "editor", - "title": "Using signals with services" + "title": "サービスでシグナルを使用する" } diff --git a/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.en.md b/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.en.md new file mode 100644 index 0000000000..aae2a5d690 --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.en.md @@ -0,0 +1,110 @@ +# Using signals with directives + +Now that you've learned [using signals with services](/tutorials/signals/7-using-signals-with-services), let's explore how directives use signals. **The great news: signals work exactly the same in directives as they do in components!** The main difference is that since directives don't have templates, you'll primarily use signals in host bindings to reactively update the host element. + +In this activity, you'll build a highlight directive that demonstrates how signals create reactive behavior in directives. + +
+ + + + +Import the signal functions and create your reactive state. This works exactly the same as in components: + +```ts +import {Directive, input, signal, computed} from '@angular/core'; + +@Directive({ + selector: '[highlight]', +}) +export class HighlightDirective { + // Signal inputs - same as components! + color = input('yellow'); + intensity = input(0.3); + + // Internal state - same as components! + private isHovered = signal(false); + + // Computed signals - same as components! + backgroundStyle = computed(() => { + const baseColor = this.color(); + const alpha = this.isHovered() ? this.intensity() : this.intensity() * 0.5; + + const colorMap: Record = { + 'yellow': `rgba(255, 255, 0, ${alpha})`, + 'blue': `rgba(0, 100, 255, ${alpha})`, + 'green': `rgba(0, 200, 0, ${alpha})`, + 'red': `rgba(255, 0, 0, ${alpha})`, + }; + + return colorMap[baseColor] || colorMap['yellow']; + }); +} +``` + +Notice how this is identical to component patterns - the only difference is we're in a `@Directive` instead of `@Component`. + + + +Since directives don't have templates, you'll use signals in **host bindings** to reactively update the host element. Add the `host` configuration and event handlers: + +```ts +@Directive({ + selector: '[highlight]', + host: { + '[style.backgroundColor]': 'backgroundStyle()', + '(mouseenter)': 'onMouseEnter()', + '(mouseleave)': 'onMouseLeave()', + }, +}) +export class HighlightDirective { + // ... signals from previous step ... + + onMouseEnter() { + this.isHovered.set(true); + } + + onMouseLeave() { + this.isHovered.set(false); + } +} +``` + +The host bindings automatically re-evaluate when the signals change - just like template bindings in components! When `isHovered` changes, the `backgroundStyle` computed signal recalculates, and the host binding updates the element's style. + + + +Update the app template to demonstrate the reactive directive: + +```ts +template: ` +
+

Directive with Signals

+ +
+ Hover me - Yellow highlight +
+ +
+ Hover me - Blue highlight +
+ +
+ Hover me - Green highlight +
+
+`, +``` + +The directive automatically applies reactive highlighting based on the signal inputs! +
+ +
+ +Perfect! You've now seen how signals work with directives. Some key takeaways from this lesson are: + +- **Signals are universal** - All signal APIs (`input()`, `signal()`, `computed()`, `effect()`) work the same in both directives and components +- **Host bindings are the primary use case** - Since directives don't have templates, you use signals in host bindings to reactively modify the host element +- **Same reactive patterns** - Signal updates trigger automatic re-evaluation of computed signals and host bindings, just like in component templates + +In the next lesson, you'll [learn how to query child elements with signal queries](/tutorials/signals/9-query-child-elements-with-signal-queries)! diff --git a/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.md b/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.md index aae2a5d690..c4a537a03c 100644 --- a/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.md +++ b/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.md @@ -1,15 +1,15 @@ -# Using signals with directives +# ディレクティブでのシグナルの使用 -Now that you've learned [using signals with services](/tutorials/signals/7-using-signals-with-services), let's explore how directives use signals. **The great news: signals work exactly the same in directives as they do in components!** The main difference is that since directives don't have templates, you'll primarily use signals in host bindings to reactively update the host element. +[サービスでのシグナルの使用](/tutorials/signals/7-using-signals-with-services)を学んだところで、ディレクティブがどのようにシグナルを使用するかを探ってみましょう。**朗報です。シグナルはコンポーネントと同じようにディレクティブでもまったく同じように機能します!**主な違いは、ディレクティブにはテンプレートがないため、ホスト要素をリアクティブに更新するために、主にホストバインディングでシグナルを使用することです。 -In this activity, you'll build a highlight directive that demonstrates how signals create reactive behavior in directives. +このアクティビティでは、シグナルがディレクティブでどのようにリアクティブな動作を作成するかを示すハイライトディレクティブを構築します。
- -Import the signal functions and create your reactive state. This works exactly the same as in components: + +シグナル関数をインポートし、リアクティブな状態を作成します。これはコンポーネントとまったく同じように機能します。 ```ts import {Directive, input, signal, computed} from '@angular/core'; @@ -42,11 +42,11 @@ export class HighlightDirective { } ``` -Notice how this is identical to component patterns - the only difference is we're in a `@Directive` instead of `@Component`. +これがコンポーネントのパターンとまったく同じであることに注目してください。唯一の違いは、`@Component`ではなく`@Directive`内にいることです。 - -Since directives don't have templates, you'll use signals in **host bindings** to reactively update the host element. Add the `host` configuration and event handlers: + +ディレクティブにはテンプレートがないため、ホスト要素をリアクティブに更新するために**ホストバインディング**でシグナルを使用します。`host`設定とイベントハンドラーを追加します。 ```ts @Directive({ @@ -70,11 +70,11 @@ export class HighlightDirective { } ``` -The host bindings automatically re-evaluate when the signals change - just like template bindings in components! When `isHovered` changes, the `backgroundStyle` computed signal recalculates, and the host binding updates the element's style. +シグナルが変更されると、ホストバインディングは自動的に再評価されます。これはコンポーネントのテンプレートバインディングと同じです!`isHovered`が変更されると、`backgroundStyle`の計算済みシグナルが再計算され、ホストバインディングが要素のスタイルを更新します。 - -Update the app template to demonstrate the reactive directive: + +リアクティブなディレクティブをデモンストレーションするために、アプリのテンプレートを更新します。 ```ts template: ` @@ -96,15 +96,15 @@ template: ` `, ``` -The directive automatically applies reactive highlighting based on the signal inputs! +ディレクティブは、シグナル入力に基づいてリアクティブなハイライトを自動的に適用します! -Perfect! You've now seen how signals work with directives. Some key takeaways from this lesson are: +完璧です!これで、シグナルがディレクティブでどのように機能するかを理解しました。このレッスンの主なポイントは次のとおりです。 -- **Signals are universal** - All signal APIs (`input()`, `signal()`, `computed()`, `effect()`) work the same in both directives and components -- **Host bindings are the primary use case** - Since directives don't have templates, you use signals in host bindings to reactively modify the host element -- **Same reactive patterns** - Signal updates trigger automatic re-evaluation of computed signals and host bindings, just like in component templates +- **シグナルは普遍的** - すべてのシグナルAPI(`input()`、`signal()`、`computed()`、`effect()`)は、ディレクティブとコンポーネントの両方で同じように機能します +- **ホストバインディングが主要なユースケース** - ディレクティブにはテンプレートがないため、ホスト要素をリアクティブに修正するためにホストバインディングでシグナルを使用します +- **同じリアクティブパターン** - シグナル更新は、コンポーネントテンプレートと同じように、計算済みシグナルとホストバインディングの自動再評価をトリガーします -In the next lesson, you'll [learn how to query child elements with signal queries](/tutorials/signals/9-query-child-elements-with-signal-queries)! +次のレッスンでは、[シグナルクエリで子要素をクエリする方法](/tutorials/signals/9-query-child-elements-with-signal-queries)を学びます! diff --git a/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/config.en.json b/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/config.en.json new file mode 100644 index 0000000000..9b72341f6c --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/config.en.json @@ -0,0 +1,5 @@ +{ + "openFiles": ["src/app/app.ts", "src/app/highlight-directive.ts", "src/app/app.css"], + "type": "editor", + "title": "Using signals with directives" +} \ No newline at end of file diff --git a/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/config.json b/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/config.json index 5df1706f90..4ca7893822 100644 --- a/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/config.json +++ b/adev-ja/src/content/tutorials/signals/steps/8-using-signals-with-directives/config.json @@ -1,5 +1,5 @@ { "openFiles": ["src/app/app.ts", "src/app/highlight-directive.ts", "src/app/app.css"], "type": "editor", - "title": "Using signals with directives" + "title": "ディレクティブでのシグナルの使用" } diff --git a/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.en.md b/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.en.md new file mode 100644 index 0000000000..8354746f5d --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.en.md @@ -0,0 +1,66 @@ +# Query child elements with signal queries + +Now that you've learned [how to use signals with directives](/tutorials/signals/8-using-signals-with-directives), let's explore signal-based query APIs. These provide a reactive way to access and interact with child components and directives. Both components and directives can perform queries while also being queried themselves. Unlike the traditional ViewChild, signal queries automatically update and provide type-safe access to child components and directives. + +In this activity, you'll add viewChild queries to interact with child components programmatically. + +
+ + + + +First, add the `viewChild` import to access child components in `app.ts`. + +```ts +import {Component, signal, computed, viewChild, ChangeDetectionStrategy} from '@angular/core'; +``` + + + + +Add viewChild queries to the App component to access child components. + +```ts +// Query APIs to access child components +firstProduct = viewChild(ProductCard); +cartSummary = viewChild(CartSummary); +``` + +These queries create signals that reference child component instances. + + + +Use the viewChild queries to call methods on child components in `app.ts`: + +```ts +showFirstProductDetails() { + const product = this.firstProduct(); + if (product) { + product.highlight(); + } +} + +initiateCheckout() { + const summary = this.cartSummary(); + if (summary) { + summary.initiateCheckout(); + } +} +``` + + + + +The control buttons should now work: + +- **"Show First Product Details"** - Calls `highlight()` on the ProductCard +- **"Initiate Checkout"** - Calls `initiateCheckout()` on the CartSummary + +Click the buttons to see how viewChild queries enable parent components to control child behavior. + + + + +Perfect! You've learned how to use signal-based query APIs for child component interaction: + +In the next lesson, you'll learn about [how to react to signal changes with effect](/tutorials/signals/10-reacting-to-signal-changes-with-effect)! diff --git a/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.md b/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.md index 8354746f5d..8d30cd1342 100644 --- a/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.md +++ b/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.md @@ -1,15 +1,15 @@ -# Query child elements with signal queries +# シグナルクエリで子要素をクエリする -Now that you've learned [how to use signals with directives](/tutorials/signals/8-using-signals-with-directives), let's explore signal-based query APIs. These provide a reactive way to access and interact with child components and directives. Both components and directives can perform queries while also being queried themselves. Unlike the traditional ViewChild, signal queries automatically update and provide type-safe access to child components and directives. +[ディレクティブでのシグナルの使い方](/tutorials/signals/8-using-signals-with-directives)を学んだところで、シグナルベースのクエリAPIについて見ていきましょう。これらは、子コンポーネントやディレクティブにアクセスして操作するためのリアクティブな方法を提供します。コンポーネントとディレクティブの両方がクエリを実行でき、またそれら自身もクエリされることがあります。従来のViewChildとは異なり、シグナルクエリは自動的に更新され、子コンポーネントやディレクティブへの型安全なアクセスを提供します。 -In this activity, you'll add viewChild queries to interact with child components programmatically. +このアクティビティでは、子コンポーネントとプログラムでやり取りするためにviewChildクエリを追加します。
- -First, add the `viewChild` import to access child components in `app.ts`. + +まず、`app.ts`で子コンポーネントにアクセスするために`viewChild`のインポートを追加します。 ```ts import {Component, signal, computed, viewChild, ChangeDetectionStrategy} from '@angular/core'; @@ -17,8 +17,8 @@ import {Component, signal, computed, viewChild, ChangeDetectionStrategy} from '@ - -Add viewChild queries to the App component to access child components. + +AppコンポーネントにviewChildクエリを追加して、子コンポーネントにアクセスします。 ```ts // Query APIs to access child components @@ -26,11 +26,11 @@ firstProduct = viewChild(ProductCard); cartSummary = viewChild(CartSummary); ``` -These queries create signals that reference child component instances. +これらのクエリは、子コンポーネントインスタンスを参照するシグナルを作成します。 - -Use the viewChild queries to call methods on child components in `app.ts`: + +viewChildクエリを使用して、`app.ts`で子コンポーネントのメソッドを呼び出します。 ```ts showFirstProductDetails() { @@ -50,17 +50,17 @@ initiateCheckout() { - -The control buttons should now work: + +コントロールボタンが動作するようになりました。 -- **"Show First Product Details"** - Calls `highlight()` on the ProductCard -- **"Initiate Checkout"** - Calls `initiateCheckout()` on the CartSummary +- **"Show First Product Details"** - ProductCardで`highlight()`を呼び出します +- **"Initiate Checkout"** - CartSummaryで`initiateCheckout()`を呼び出します -Click the buttons to see how viewChild queries enable parent components to control child behavior. +ボタンをクリックして、viewChildクエリが親コンポーネントによる子コンポーネントの動作制御をどのように可能にするかを確認してください。 -Perfect! You've learned how to use signal-based query APIs for child component interaction: +完璧です!子コンポーネントのインタラクションのためにシグナルベースのクエリAPIを使用する方法を学びました。 -In the next lesson, you'll learn about [how to react to signal changes with effect](/tutorials/signals/10-reacting-to-signal-changes-with-effect)! +次のレッスンでは、[effectでシグナルの変更に反応する方法](/tutorials/signals/10-reacting-to-signal-changes-with-effect)について学びます! diff --git a/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/config.en.json b/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/config.en.json new file mode 100644 index 0000000000..2c215a2b4d --- /dev/null +++ b/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/config.en.json @@ -0,0 +1,10 @@ +{ + "openFiles": [ + "src/app/app.ts", + "src/app/product-card.ts", + "src/app/cart-summary.ts", + "src/app/app.css" + ], + "type": "editor", + "title": "Query child elements with signal queries" +} \ No newline at end of file diff --git a/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/config.json b/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/config.json index 148894a291..ebf174ebea 100644 --- a/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/config.json +++ b/adev-ja/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/config.json @@ -6,5 +6,5 @@ "src/app/app.css" ], "type": "editor", - "title": "Query child elements with signal queries" + "title": "シグナルクエリで子要素をクエリする" }