スタンドアロン コンポーネント スタートガイド

1. はじめに

作業内容

この Codelab では、Angular v14 を使用して野生動物の写真ギャラリー アプリを作成します。アプリが完成すると、一連の写真が表示されます。また、写真の撮影者に連絡するためのメッセージ送信フォームと、写真に写っている動物に関する興味深い情報を確認できるチャット ウィンドウも表示されます。

Angular v14 と新しいスタンドアロン コンポーネント機能を使用して、アプリ内のすべてをビルドします。

Angular フレームワークと Angular CLI へのすべての参照は、Angular v14 を反映しています。スタンドアロン コンポーネントは Angular v14 のプレビュー機能であるため、Angular v14 を使用してまったく新しいアプリケーションを作成する必要があります。スタンドアロン コンポーネントを使用すると、Angular アプリケーションを簡単に構築できます。スタンドアロン コンポーネント、スタンドアロン ディレクティブ、スタンドアロン パイプは、NgModules の必要性を減らしてオーサリング エクスペリエンスを効率化することを目的としています。スタンドアロン コンポーネントは、Angular ライブラリの既存のエコシステムを最大限に活用できます。

これが、今日作成するアプリケーションです。

申請が完了しました

学習内容

  • Angular CLI を使用して新しいプロジェクトをスキャフォールドする方法
  • Angular スタンドアロン コンポーネントを使用して Angular アプリの開発を効率化する方法
  • スタンドアロン コンポーネントを作成する方法(UI を構築してビジネス ロジックを追加する方法)
  • スタンドアロン コンポーネントを使用してアプリケーションをブートストラップする方法
  • スタンドアロン コンポーネントを遅延読み込みする方法
  • Dialogflow Messenger を使用してスタンドアロン コンポーネントにチャット ダイアログを埋め込む方法
  • Google Cloud CLI(gcloud)を使用して Angular アプリケーションを Google Cloud App Engine にデプロイする方法

必要なもの

  • Gmail または Google Workspace アカウント
  • 次の分野に関する基本的な知識
    • HTML です。要素を作成する方法。
    • CSS と Less です。CSS セレクタを使用してスタイル定義ファイルを作成する方法。
    • TypeScript または JavaScript です。DOM 構造を操作する方法。
    • git と GitHub です。リポジトリのフォークとクローンを作成する方法。
    • コマンドライン インターフェース(bashzsh など)。ディレクトリを移動してコマンドを実行する方法。

2. 環境設定

ローカル環境を設定する

この Codelab を完了するには、ローカル コンピュータに次のソフトウェアをインストールする必要があります。

  • Node.js のアクティブな LTS またはメンテナンス LTS バージョン。Angular フレームワークと Angular CLI のインストールに使用します。

    ノードのバージョン

    Angular でサポート

    14.15 以降

    サポート対象

    16.10 以降

    サポート対象

    18.1.0

    サポート対象外

    ローカル コンピュータで Node.js のバージョンを確認するには、コマンドライン ウィンドウから次の node コマンドを実行します。
    node -v
    
  • コードエディタまたは IDEファイルを開いて編集するために使用します。Visual Studio Code、または任意のコードエディタを使用します。

Angular CLI をインストールする

すべての依存関係を構成したら、次の npm コマンドを実行して、コマンドライン ウィンドウから Angular CLI をインストールします。

npm install --global @angular/cli

構成が正しいことを確認するには、コマンドラインから次の Angular コマンドを実行します。

ng version

Angular コマンドが正常に完了すると、次のようなスクリーンショットに類似したメッセージが表示されます。

Angular バージョンのターミナル出力

ソースコードと画像

この Codelab では、アプリ全体をゼロから作成します。GitHub リポジトリには最終的なコードが含まれています。問題が解決しない場合は、最終的なコードとギャラリー ページに表示される画像を確認してください。

ソースコードをダウンロードするには:

  1. ブラウザで次のページに移動します。
    https://github.com/angular/codelabs/tree/standalone-components
    
  2. コマンドライン ウィンドウで、リポジトリのフォークとクローンを作成します。

次のステップでは、フォト ギャラリー アプリケーションをビルドします。

3. 新しいアプリケーションを作成する

最初のスターター アプリケーションを作成するには、次の操作を行います。

Angular CLI を使用して新しいワークスペースを作成します。Angular CLI と Angular フレームワークの詳細については、angular.io をご覧ください。

新しいプロジェクトを作成

コマンドライン ウィンドウで、次の操作を行います。

  1. 次の Angular コマンドを入力して、photo-gallery-app という名前の新しい Angular プロジェクトを作成します。
    ng new photo-gallery-app
    
  2. プロンプトごとにデフォルトを選択します。Angular フレームワークによって、必要なパッケージと依存関係がインストールされます。このプロセスには数分かかる場合があります。

Angular CLI が完了すると、新しい Angular ワークスペースと、すぐに実行できるシンプルなアプリケーションが作成されます。

新しいアプリケーションは、標準の Angular アプリケーションのように構成されています。この Codelab では、新しいアプリケーションの NgModule は不要です。

アプリケーション モジュールを削除する

アプリケーション モジュールを削除するには、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src/app ディレクトリに移動します。
  2. ファイル app.module.ts を削除します。

アプリケーション モジュールを削除すると、アプリケーションにモジュールが存在しなくなります。アプリケーションにコンポーネントが 1 つしかない場合(アプリケーション コンポーネントのみの場合)、そのコンポーネントをスタンドアロンとして宣言する必要があります。

スタンドアロン コンポーネントを宣言する

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src/app ディレクトリに移動します。
  2. app.component.ts ファイルを開きます。
  3. 次のパラメータと値をデコレータのリストに追加します。
    standalone: true
    
    app.component.ts ファイルは次のコード例とほぼ同じにする必要があります。
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      standalone: true
    })
    export class AppComponent {
      title = 'photo-gallery-app';
    }
    
  4. app.component.ts ファイルを保存します。

新しいスタンドアロン アプリケーションをコンパイルする

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力して、新しいアプリをコンパイルします。
    ng serve
    

アプリケーションはコンパイルされません。修正が必要な問題がいくつかあります。

bootstrapApplication API を使用する

NgModule なしでアプリケーションを実行できるようにするには、bootstrapApplication API を使用し、ルート コンポーネントとしてスタンドアロン コンポーネントを使用する必要があります。

アプリケーション モジュールへの参照を削除する

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src ディレクトリに移動します。
  2. main.ts ファイルを開きます。
  3. アプリケーション モジュールがなくなったため、次のインポート コードを削除します。
    import { AppModule } from './app/app.module';
    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    
  4. アプリケーション モジュールがないため、次のブートストラップ コードを削除します。
    platformBrowserDynamic().bootstrapModule(AppModule)
      .catch(err => console.error(err));
    
    main.ts ファイルは次のコード例と一致している必要があります。
    import { enableProdMode } from '@angular/core';
    import { environment } from './environments/environment';
    
    if (environment.production) {
      enableProdMode();
    }
    

bootstrapApplication コンポーネントを追加する

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src ディレクトリに移動します。
  2. main.ts ファイルを開きます。
  3. @angular/platform-browser サービスから bootstrapApplication コンポーネントをインポートします。
    import { bootstrapApplication } from '@angular/platform-browser';
    
  4. 次のコードを追加して、アプリケーションをブートストラップします。
    bootstrapApplication(AppComponent).catch(err => console.error(err));
    
  5. コンポーネントと必要なライブラリをインポートします。
    import { AppComponent } from './app/app.component';
    
    main.ts ファイルは次のコード例と一致している必要があります。
    import { enableProdMode } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { AppComponent } from './app/app.component';
    import { environment } from './environments/environment';
    
    if (environment.production) {
      enableProdMode();
    }
    
    bootstrapApplication(AppComponent).catch(err => console.error(err));
    

ルーターと共通モジュールを追加する

Router などの一般的なモジュール機能を使用するには、各モジュールをコンポーネントに直接インポートする必要があります。

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src/app ディレクトリに移動します。
  2. app.component.ts ファイルを開きます。
  3. 必要なモジュールをコンポーネントにインポートします。
    import { CommonModule } from '@angular/common';
    import { RouterModule } from '@angular/router';
    
  4. コンポーネントにインポートを追加します。
    imports: [CommonModule, RouterModule],
    
    app.component.ts ファイルは次のコード例と一致している必要があります。
    import { Component } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { RouterModule } from '@angular/router';
    
    @Component({
      selector: 'app-root',
      imports: [CommonModule, RouterModule],
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      standalone: true
    })
    export class AppComponent {
      title = 'photo-gallery-app';
    }
    
  5. app.component.ts ファイルを保存します。

新しいスタンドアロン アプリケーションをコンパイルして実行する

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力して、アプリケーションをコンパイルして実行し、ウェブサーバーを起動します。コンパイル エラーを削除するには、アプリケーションを実行する前に IDE を閉じる必要がある場合があります。
    ng serve
    

開発用サーバーは、ポート 4200 で実行する必要があります。以前のエラーはすべて解消され、コンパイルが正常に完了しているはずです。おつかれさまでした。モジュールなしでスタンドアロン コンポーネントを使用して実行される Angular アプリケーションが正常に作成されました。

  1. 次に、写真を表示するようにアプリを美化します。

4. 写真を表示します

新しいアプリはフォト ギャラリーとして設計されており、いくつかの写真を表示する必要があります。

コンポーネントは、Angular アプリの核となる構成要素です。コンポーネントには主に 3 つの側面があります。

  • テンプレートの HTML ファイル
  • スタイルの CSS ファイル
  • アプリの動作に関する TypeScript ファイル

写真をアプリケーションに移動する

画像は、先ほど GitHub からダウンロードしたアプリに用意されています。

  1. GitHub プロジェクトの src/assets ディレクトリに移動します。
  2. ファイルを photo-gallery-app プロジェクト ディレクトリの analogue ディレクトリにコピーして貼り付けます。

HTML テンプレートを作成する

app.component.html ファイルは、AppComponent コンポーネントに関連付けられた HTML テンプレート ファイルです。

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src/app ディレクトリに移動します。
  2. app.component.html ファイルを開きます。
  3. 既存の HTML をすべて削除します。
  4. 次のコードサンプルから HTML をコピーして貼り付けます。
    <article>
        <h1>Above and below the Ocean</h1>
            <h2>A taste of the Australia and Galapagos Wildlife, meet my friends!</h2>
            <section>
                <section class="row">
                    <div class="column">
                      <img src="/assets/49412593648_8cc3277a9c_c.jpg">
                      <img src="/assets/49413271167_22a504c3fa_w.jpg">
                      <img src="/assets/47099018614_5a68c0195a_w.jpg">
                    </div>
                    <div class="column">
                      <img src="/assets/41617221114_4d5473251c_w.jpg">
                      <img src="/assets/47734160411_f2b6ff8139_w.jpg"> 
                      <img src="/assets/46972303215_793d32957f_c.jpg">
                    </div>
                    <div class="column">
                      <img src="/assets/45811905264_be30a7ded6_w.jpg">
                      <img src="/assets/44718289960_e83c98af2b_w.jpg">
                      <img src="/assets/46025678804_fb8c47a786_w.jpg">
                    </div>
                  </section>
            </section>
    </article
    
  5. app.component.html ファイルを保存します。

スタイル定義ファイルを作成する

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src ディレクトリに移動します。
  2. styles.css ファイルを開きます。
  3. 次のコードサンプルから CSS をコピーして貼り付けます。
    article {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      font-family: 'Raleway';
    }
    
    h1 {
      color: #4479BA;
      text-align: center;
      font-size: xx-large;
    }
    
    h2 {
      color: rgb(121, 111, 110);
      text-align: center;
    }
    
    .row {
      display: flex;
      flex-wrap: wrap;
      padding: 0 4px;
    }
    
    /*   Create four equal columns that sits next to each other */
    .column {
      flex: 25%;
      padding: 0 4px;
    }
    
    .column img {
      margin-top: 8px;
      vertical-align: middle;
      width: 100%;
    }
    
    .link_button {
      -webkit-border-radius: 4px;
      -moz-border-radius: 4px;
      border-radius: 4px;
      border: solid 1px #20538D;
      text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
      -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      background: #4479BA;
      color: #FFF;
      padding: 8px 12px;
      text-decoration: none;
      margin-top: 50px;
      font-size: large;
    }
    
    @media screen and (max-width: 800px) {
      .column {
        flex: 50%;
        max-width: 50%;
      }
    }
    
    @media screen and (max-width: 600px) {
      .column {
        flex: 100%;
        max-width: 100%;
      }
    }
    
    
  4. styles.css ファイルを保存します。

インデックス ファイルを更新する

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src ディレクトリに移動します。
  2. index.html ファイルを開きます。
  3. Raleway フォントを追加して、すべてのページで継承できるようにします。
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
    
  4. index.html ファイルを保存します。
  5. コードを保存してブラウザを確認します。開発用サーバーが実行されている状態で、保存すると変更がブラウザに反映されます。
  6. 次に、フィードバックを送信し、Jimbo とチャットするための新しいスタンドアロン コンポーネントを作成します。この Codelab で、Jimbo について詳しく学びましょう。

5. 新しいスタンドアロン コンポーネントを追加する

ここまで見てきたように、スタンドアロン コンポーネントを使用すると、NgModule の必要性が減り、Angular アプリケーションを簡単に構築できます。以降のセクションでは、ユーザーがフィードバックを送信したり、仮想エージェントとチャットしたりできる新しいスタンドアロン コンポーネントを作成します。

新しいスタンドアロン コンポーネントを作成する

この新しいコンポーネントを作成するには、Angular CLI をもう一度使用します。

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力して、feedback-and-chat という名前の新しいコンポーネントを作成します。
    ng generate component feedback-and-chat --standalone
    
    次の表に、コマンドの各部分について説明します。

    パーツ

    詳細

    ng

    Angular フレームワークのすべての Angular CLI コマンドを定義します。

    generate component

    新しいコンポーネントの基盤を作成します。

    feedback-and-chat

    コンポーネントの名前

    --standalone

    Angular フレームワークにスタンドアロン コンポーネントを作成するよう指示します。

新しいスタンドアロン コンポーネントをインポートする

新しいスタンドアロン コンポーネントを使用するには、まず app.components.ts ファイルの imports 配列に追加する必要があります。

これはスタンドアロン コンポーネントであるため、モジュールのようにインポートします。

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src/app ディレクトリに移動します。
  2. app.component.ts ファイルを開きます。
  3. 新しいスタンドアロン コンポーネントをインポートします。
    import { FeedbackAndChatComponent } from './feedback-and-chat/feedback-and-chat.component';
    
  4. コンポーネントのインポートを更新します。
    imports: [CommonModule, RouterModule, FeedbackAndChatComponent],
    
    app.component.ts ファイルは次のコード例と一致している必要があります。
    import { CommonModule } from '@angular/common';
    import { Component } from '@angular/core';
    import { RouterModule } from '@angular/router';
    import { FeedbackAndChatComponent } from './feedback-and-chat/feedback-and-chat.component';
    
    @Component({
      selector: 'app-root',
      imports: [CommonModule, RouterModule, FeedbackAndChatComponent],
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      standalone: true
    })
    export class AppComponent {
      title = 'photo-gallery-app';
    }
    
  5. app.component.ts ファイルを保存します。

コンポーネントを遅延読み込みする

イージーラウディングのパラダイムから、必要になるまでコードがクライアントに送信されない遅延読み込みのパラダイムに切り替えます。遅延読み込みは、ページの読み込み時間を短縮し、パフォーマンスを向上させ、ユーザー エクスペリエンスを改善するための優れた方法です。ルーターが遅延読み込みを処理します。これは、ngModule とスタンドアロン コンポーネントについても同様です。

アプリケーション コンポーネントに関連付けられた HTML テンプレートを更新する

スタンドアロン コンポーネントを遅延読み込みするには、ユーザーが選択したときにのみコンポーネントを有効にするボタンを UI に追加します。

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src/app ディレクトリに移動します。
  2. app.component.html ファイルを開きます。
  3. ファイルの末尾までスクロールして、次のコードサンプルを追加してから、article 要素を閉じます。
    <a class="link_button" routerLink="feedback-and-chat">Find out more about these guys!</a>
    <router-outlet></router-outlet> 
    
  4. app.component.html ファイルは次のコード例と一致している必要があります。
    <article>
        <h1>Above and below the Ocean</h1>
        <h2>A taste of the Australia and Galapagos Wildlife, meet my friends!</h2>
        <section>
            <section class="row">
                <div class="column">
                    <img src="/assets/49412593648_8cc3277a9c_c.jpg">
                    <img src="/assets/49413271167_22a504c3fa_w.jpg">
                    <img src="/assets/47099018614_5a68c0195a_w.jpg">
                </div>
                <div class="column">
                    <img src="/assets/41617221114_4d5473251c_w.jpg">
                    <img src="/assets/47734160411_f2b6ff8139_w.jpg"> 
                    <img src="/assets/46972303215_793d32957f_c.jpg">
                </div>
                <div class="column">
                    <img src="/assets/45811905264_be30a7ded6_w.jpg">
                    <img src="/assets/44718289960_e83c98af2b_w.jpg">
                    <img src="/assets/46025678804_fb8c47a786_w.jpg">
                </div>
            </section>
        </section> 
        <a class="link_button" routerLink="feedback-and-chat">Find out more about these guys!</a>
        <router-outlet></router-outlet>
    </article>
    
  5. app.component.html ファイルを保存します。

ルートを構成する

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリの src ディレクトリに移動します。
  2. main.ts ファイルを開きます。
  3. provideRouter メソッドと Routes モジュールをインポートします。Angular v 14.2.0 では、アプリケーションのルートのセットを構成できる新しい provideRouter メソッドが導入されました。
    import { provideRouter, Routes } from '@angular/router';
    
  4. 次のコード スニペットをインポートと if ステートメントの間にコピーして貼り付けます。
    const routes = [
      {
        path: 'feedback-and-chat',
        loadComponent: () => import('./app/feedback-and-chat/feedback-and-chat.component').then(c => c.FeedbackAndChatComponent),
      }
    ]
    
  5. 次のコード スニペットをコピーして貼り付け、bootstrapApplication メソッドを置き換えます。
    bootstrapApplication(AppComponent, {
      providers: [
        provideRouter(routes)
      ]
    }).catch(err => console.error(err));
    
    main.ts ファイルは、次のコードサンプルと一致する必要があります。
    import { enableProdMode } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { provideRouter, Routes } from '@angular/router';
    import { AppComponent } from './app/app.component';
    import { environment } from './environments/environment';
    
    const routes = [
      {
        path: 'feedback-and-chat',
        loadComponent: () => 
          import('./app/feedback-and-chat/feedback-and-chat.component').then(c => c.FeedbackAndChatComponent),
      }
    ]
    
    if (environment.production) {
      enableProdMode();
    }
    
    bootstrapApplication(AppComponent, {
      providers: [
        provideRouter(routes)
      ]
    }).catch(err => console.error(err));
    
  6. main.ts ファイルを保存します。

Chrome デベロッパー ツールでコンパイルとレビューを行う

Chrome デベロッパー ツールを使用して、Angular フレームワークがコンポーネントを遅延読み込みする方法を確認します。

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力して、アプリケーションをコンパイルして実行し、ウェブサーバーを起動します。
    ng serve
    
    開発用サーバーはポート 4200 で実行する必要があります。

ブラウザで次の操作を行います。

  1. 次のページに移動します。
    http://localhost:4200
    
  2. Chrome デベロッパー ツールを開き、[ネットワーク] タブを選択します。
  3. ページを更新して複数のファイルを表示しますが、feedback-and-chat コンポーネントは表示されません。画面が次のスクリーン キャプチャと一致しているはずです。Chrome DevTools パネルが開いているアプリのスクリーンショット
  4. [Find out more about these guys!] ボタンを選択してスタンドアロン コンポーネントに移動します。ログには、完全なルーターがヒットしたときにのみコンポーネントが読み込まれたことが示されます。リストの最後までスクロールして、コンポーネントが読み込まれていることを確認します。画面は次のスクリーンショットと同じになるはずです。Chrome DevTools パネルが開いていて、遅延読み込みコンポーネントを示しているアプリのスクリーンショット

6. フォームの UI を追加する

フィードバック送信フォームには 3 つの入力 UI フィールドと、下部にボタンがあります。3 つの入力 UI フィールドは、氏名、送信者のメールアドレス、コメントです。

UI をサポートするには、3 つの入力 UI フィールドに関連付けられた各 contactForm フォーム コントロールにバインドする formControlName 属性を input 要素に追加します。

フォームを HTML テンプレートに追加する

ユーザーがフィードバックを送信できるように、UI にフォームを追加します。

コードエディタで、次の操作を行います。

  1. feedback-and-chat.component.html ファイルに移動する
  2. 既存の HTML を削除します。
  3. 次のコードサンプルの HTML をコピーして貼り付けます。
    <article>    
        <h2>Send me a message or use the chat below to learn some cool facts of the animals in the photos</h2>
        <section class="container">
            <form ngNativeValidate [formGroup]="contactForm" (ngSubmit)="onSubmit()">
                <div class="row" *ngIf="showMsg">
                    <div class="row">
                        <p>
                            <strong>Thanks for your message!</strong>
                        </p>
                    </div>
                </div>
                <div class="row">
                    <div class="col-25">
                        <label for="name">Full Name</label>
                    </div>
                    <div class="col-75">
                        <input type="text" id="fname" placeholder="Your name.." formControlName="fullname" required>
                    </div>
                </div>
                <div class="row">
                    <div class="col-25">
                        <label for="lemail">Email</label>
                    </div>
                    <div class="col-75">
                        <input type="text" id="lemail" placeholder="Your email.." formControlName="email" required>
                    </div>
                </div>
                <div class="row">
                    <div class="col-25">
                        <label for="comments">Comments</label>
                    </div>
                    <div class="col-75">
                        <textarea id="subject" formControlName="comments" placeholder="Write something.." style="height:200px" required></textarea>
                    </div>
                </div>
                <div class="row">
                  <button type="submit" class="submit">Submit</button>
                </div>
            </form>
        </section>
    </article>
    
  4. feedback-and-chat.component.html ファイルを保存します。

フォームのスタイル ファイルを更新する

コードエディタで、次の操作を行います。

  1. feedback-and-chat.component.css ファイルに移動する
  2. 次のサンプルコードの CSS をコピーして貼り付けます。
    /*   Style inputs, select elements and textareas */
    input[type=text], select, textarea{
      width: 100%;
      padding: 12px;
      border: 1px solid #ccc;
      border-radius: 4px;
      box-sizing: border-box;
      resize: vertical;
    }
    
    /*   Style the label to display next to the inputs */
    label {
      padding: 12px 12px 12px 0;
      display: inline-block;
    }
    
    /*   Style the submit button */
    button {
      background-color: #4479BA;
      color: white;
      padding: 12px 20px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      float: right;
      font-size: medium;
      font-family: 'Raleway';
    }
    
    /*   Style the container */
    .container {
      border-radius: 5px;
      background-color: #f2f2f2;
      padding: 20px;
      width: 100%;
    }
    
    /*   Floating column for labels: 25% width */
    .col-25 {
      float: left;
      width: 25%;
      margin-top: 6px;
    }
    
    /*   Floating column for inputs: 75% width */
    .col-75 {
      float: left;
      width: 75%;
      margin-top: 6px;
    }
    
    /*   Clear floats after the columns */
    .row:after {
      content: "";
      display: table;
      clear: both;
    }
    
    /*   Responsive layout - when the screen is less than 600px wide, make the two columns stack on top of each other instead of next to each other */
    @media screen and (max-width: 600px) {
      .col-25, .col-75, input[type=submit] {
        width: 100%;
        margin-top: 0;
      }
    }
    
  3. feedback-and-chat.component.css ファイルを保存します。

フォームの UI 更新をコンパイルする

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力して、アプリケーションをコンパイルして実行し、ウェブサーバーを起動します。
    ng serve
    
    アプリケーションはコンパイルされません。フォームをバインドする必要があります。
  3. 現時点では、以下の項目を確認してください。
    • formGroup プロパティ バインディングを使用して、contactFormform 要素と ngSubmit イベント バインディングにバインドします。
    • FormGroup ディレクティブは、form 要素によって生成された送信イベントをリッスンします。その後、FormGroup ディレクティブは ngSubmit イベントを出力します。このイベントは、onSubmit コールバック関数にバインドできます。
    • 後で、feedback-and-chat.component.ts ファイルに onSubmit コールバック関数を実装します。
  4. 次に、フォームをバインドします。

7. フォームにイベント処理を追加する

[フィードバックを送信] フォームの UI は完成していますが、インタラクションがありません。フォームによるユーザー入力の処理は、多くの一般的なアプリケーションの基盤となります。

実際のシナリオでは、次のアクションを完了するためにビジネス ロジックを実装する必要があります。

  1. コンポーネントに関連付けられたレンダリングされた DOM 構造からユーザー入力を解析します。
  2. ユーザー入力を検証します。これには、bot によるスパムを回避するための CAPTCHA や同様のメカニズムを含めます。
  3. 指定したメールアドレスにメールを送信します。
  4. ユーザーにわかりやすいメッセージを表示します。

この Codelab では、次のアクションのみを実装します。

  1. コンポーネントに関連付けられたレンダリングされた DOM 構造からユーザー入力を解析します。
  2. ユーザーにわかりやすいメッセージを表示します。

スキルを磨き、4 つのアクションをすべて実装する必要があります。

メッセージ送信フォーム モデルをコンポーネントに追加する

フィードバック送信フォームのモデルを作成して、コンポーネント クラスに追加します。フォームのステータスはフォームモデルによって決まります。FormBuilder サービスは、UI コントロールを作成するための便利なメソッドを提供します。

コードエディタで、次の操作を行います。

  1. feedback-and-chat.component.ts ファイルに移動する
  2. @angular/forms パッケージから FormBuilder サービスと ReactiveModule モジュールをインポートします。このサービスは、コントロールを生成するための便利なメソッドを提供します。次のステップでは inject 関数を利用するので、これも @angular/core からインポートする必要があります。
    import { Component, inject, OnInit } from '@angular/core';
    import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
    
  3. ReactiveFormsModule モジュールをインポートします。
    imports: [CommonModule,ReactiveFormsModule],
    
  4. 次のコンストラクタを削除します。
    constructor() { }
    
  5. クラス シグネチャのすぐ下の inject 関数を介して FormBuilder サービスを挿入します。
    private formBuilder = inject(FormBuilder);
    
    FormBuilder サービスの group メソッドを使用してフォームモデルを作成し、ユーザーの名前、メールアドレス、コメントを収集します。
  6. 新しい contactForm プロパティを作成し、group メソッドを使用してフォームモデルに設定します。フォームモデルには、nameemailcomments フィールドが含まれています。
    contactForm = this.formBuilder.group({
      fullname: '',
      email: '',
      comments: ''
    });
    
    フォームを処理するための onSubmit メソッドを定義します。実際のシナリオでは、onSubmit メソッドを使用すると、ユーザーは指定されたメールアドレスに送信されるメール メッセージを使用してフォトグラファーにフィードバック メッセージを送信できます。この Codelab では、ユーザー入力を表示し、reset メソッドを使用してフォームをリセットし、ユーザー フレンドリーな成功メッセージを表示します。
  7. 新しい onSubmit メソッドを追加し、showMsg 変数を初期化後に true に設定します。
    showMsg: boolean = false;
    
    onSubmit(): void {
      console.log('Your feedback has been submitted', this.contactForm.value);
      this.showMsg = true;
      this.contactForm.reset();
    }
    
    feedback-and-chat.component.ts ファイルは次のコード例と一致している必要があります。
    import { Component, inject, OnInit } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
    
    @Component({
      selector: 'app-feedback-and-chat',
      standalone: true,
      imports: [CommonModule, ReactiveFormsModule],
      templateUrl: './feedback-and-chat.component.html',
      styleUrls: ['./feedback-and-chat.component.css']
    })
    export class FeedbackAndChatComponent {
    
      showMsg: boolean = false;
      private formBuilder = inject(FormBuilder);
    
      contactForm = this.formBuilder.group({
        fullname: '',
        email: '',
        comments: ''
      });
    
      ngOnInit(): void {
      }
    
      onSubmit(): void {
        console.log('Your feedback has been submitted', this.contactForm.value);
        this.showMsg = true;
        this.contactForm.reset();
      }
    }
    
  8. feedback-and-chat.component.ts ファイルを保存します。

フィードバック送信フォーム モデルをコンパイルして表示する

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力して、アプリケーションをコンパイルして実行し、ウェブサーバーを起動します。
    ng serve
    
  3. 開発用サーバーはポート 4200 で実行する必要があります。

ブラウザで次の操作を行います。

  1. 次のページに移動します。
    http://localhost:4200
    
  2. Chrome デベロッパー ツールを開き、[コンソール] タブを選択します。
  3. [氏名]、[メールアドレス]、[コメント] の各テキスト ボックスに値を入力します。
  4. [送信] ボタンを選択します。ページに成功メッセージが表示されます。
  5. [コンソール] タブに表示される値を確認します。画面は次のスクリーンショットと同じになるはずです。フォームに入力された JSON データを表示するコンソールを含むブラウザ ウィンドウコンポーネント UI にメッセージ送信フォームを追加し、ユーザー入力を解析するコードが正常に実装されました。
  6. 次に、チャット ダイアログを埋め込んで、アプリケーションの訪問者が Jimbo と話せるようにします。ジムボはコアラで、野生動物に関する興味深い情報を教えてくれます。

8. チャット ダイアログを追加する

Dialogflow CX などの会話型インターフェースや同様のプラットフォームの経験を活用します。Dialogflow CX エージェントは、人間との同時会話を処理する仮想エージェントです。人間の言語のニュアンスを認識し、会話中のエンドユーザーのテキストや音声をアプリやサービスが理解できる構造化データに変換する自然言語理解モジュールです。

サンプルの仮想エージェントがすでに作成されています。このラボでは、スタンドアロン コンポーネントにチャット ダイアログを追加して、アプリケーション ユーザーがボットを操作できるようにします。この要件では、カスタマイズ可能なダイアログ ウィンドウを提供する事前構築済みの統合である Dialogflow Messenger を利用します。チャット ダイアログを開くと、画面の右下に表示されます。エージェントのデフォルトのウェルカム インテントをトリガーします。bot がユーザーに挨拶して会話を開始します。

次の実装では、野生動物に関する興味深い情報をユーザーと共有します。仮想エージェントに関するその他の実装では、顧客の複雑なユースケース(人間のコールセンター エージェントなど)に対応できる場合があります。多くの企業は、企業のウェブサイトとのコミュニケーションの主要なチャネルとしてバーチャル エージェントを使用しています。

コンポーネントに Dialogflow Messenger を追加する

フォームと同様に、チャット ダイアログはスタンドアロン コンポーネントが読み込まれたときにのみ表示する必要があります。

コードエディタで、次の操作を行います。

  1. feedback-and-chat.component.ts ファイルに移動する
  2. 次のコード例の df-messenger 要素をコピーして、ページの任意の場所に貼り付けます。
    <df-messenger agent-id="762af666-79f7-4527-86c5-9ca06f72c317"
                  chat-title="Chat with Jimbo!"
                  df-cx="true"
                  intent="messanger-welcome-event"
                  language-code="en"
                  location="us-central1"></df-messenger>
    
    Dialogflow Messenger インテグレーションを選択すると、Dialogflow によって df-messenger 要素の属性が生成されます。

    属性

    詳細

    agent-id

    事前入力済み。Dialogflow エージェントの一意の識別子を指定します。

    チャットのタイトル

    事前入力済み。チャット ダイアログの上部に表示するコンテンツを指定します。最初はエージェントの名前が入力されていますが、カスタマイズする必要があります。

    df-cx

    インタラクションが CX エージェントであることを示します。値を true に設定します。

    インテント

    チャット ダイアログが開いたときに最初のインテントをトリガーするカスタム イベントを指定します。

    language-code

    最初のインテントのデフォルトの言語コードを指定します。

    場所

    エージェントをデプロイするリージョンを指定します。

  3. feedback-and-chat.component.ts ファイルを保存します。

フィードバック送信フォーム モデルを表示する

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力して、アプリケーションをコンパイルします。
    ng serve
    
    アプリはコンパイルに失敗します。コマンドラインには次のエラー メッセージが表示されます。df-messenger のエラー メッセージ
  3. 次に、カスタム スキーマを追加します。

スタンドアロン コンポーネントにカスタム スキーマを追加する

df-messanger 要素は既知の要素ではありません。これはカスタム ウェブ コンポーネントです。Angular フレームワークのエラー メッセージは、メッセージを抑制するには、両方のスタンドアロン コンポーネントに CUSTOM_ELEMENTS_SCHEMA を追加する必要があることを示唆しています。

コードエディタで、次の操作を行います。

  1. feedback-and-chat.component.ts ファイルに移動する
  2. CUSTOM_ELEMENTS_SCHEMA スキーマをインポートします。
    import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit } from '@angular/core';
    
  3. スキーマのリストに CUSTOM_ELEMENTS_SCHEMA を追加します。
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
    
    feedback-and-chat.component.ts ファイルは次のコード例と一致している必要があります。
    import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
    
    @Component({
      selector: 'app-feedback-and-chat',
      standalone: true,
      imports: [CommonModule,ReactiveFormsModule],
      templateUrl: './feedback-and-chat.component.html',
      styleUrls: ['./feedback-and-chat.component.css'],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    
    ...
    
  4. df-messanger ウェブ コンポーネントには、フィードバック コンポーネントとチャット コンポーネントが読み込まれたときにのみ挿入される JavaScript が必要です。この目的のために、関連するコードを ngOnInit() メソッドに追加します。これにより、 要素を有効化するために必要なチャット スクリプトが読み込まれます。
    ngOnInit() {
        // Load the chat script, which activates the `<df-messenger>` element.
        const script = document.createElement('script');
        script.async = true;
        script.src = 'https://www.gstatic.com/dialogflow-console/fast/messenger-cx/bootstrap.js?v=1';
        document.head.appendChild(script);
    }
    
  5. feedback-and-chat.component.ts ファイルを保存します。

更新されたチャット ダイアログをコンパイルして表示する

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力して、アプリケーションをコンパイルして実行し、ウェブサーバーを起動します。
    ng serve
    
    開発用サーバーはポート 4200 で実行する必要があります。

ブラウザで次の操作を行います。

  1. 次のページに移動します。
    http://localhost:4200
    
    ページの下部にチャット アイコンが表示されます。
  2. アイコンを選択して Jimbo とやり取りします。Jimbo は動物に関する興味深い情報を提供します。メッセンジャー ボットが返信しているチャット ウィンドウを表示するアプリ
  3. このアプリケーションは完全に機能します。

9. アプリケーションを Google App Engine にデプロイする

アプリケーションがローカルマシンで実行されている。この Codelab の最後のステップとして、Google App Engine にデプロイします。

Google App Engine の詳細については、App Engine をご覧ください。

Google App Engine の環境を設定する

次のすべての条件をすでに満たしている場合は、次の手順をスキップして、アプリケーションのデプロイに進みます。

  • App Engine を使用して Cloud プロジェクトを作成した
  • Cloud Build API を有効にした
  • Google Cloud CLI がインストールされていること

次の操作を行います。

  1. Gmail または Google Workspace のアカウントにログインします。アカウントをお持ちでない場合は、Google アカウントを作成してください。
  2. Cloud リソースと API を使用できるように、Cloud コンソールで課金を有効にします。詳細については、セルフサービスの Cloud 請求先アカウントの作成、変更、閉鎖をご覧ください。
  3. App Engine アプリケーション リソースと他の Google Cloud リソースを保持する Google Cloud プロジェクトを作成します。詳しくは、プロジェクトの作成と管理をご覧ください。
  4. Cloud コンソールで Cloud Build API を有効にします。詳細については、API へのアクセスを有効にするをご覧ください。
  5. Google Cloud CLI と gcloud コマンドライン ツールをインストールします。詳細については、gcloud CLI をインストールするをご覧ください。
  6. Google Cloud CLI を初期化し、デプロイ先の Google Cloud プロジェクトを使用するように gcloud が構成されていることを確認します。詳細については、gcloud CLI の初期化をご覧ください。

スタンドアロン アプリケーションを作成する

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次の Angular コマンドを入力し、アプリケーションをコンパイルして本番環境用バージョンを作成します。
    ng build
    

アプリケーションの製品版が、photo-gallery-app プロジェクト ディレクトリの dist サブディレクトリに作成されます。

10. Express.js フレームワークを使用してアプリケーションをデプロイする

この Codelab のサンプルコードでは、Express.js フレームワークを使用して HTTP リクエストを処理します。任意のウェブ フレームワークを使用できます。

Express.js フレームワークをインストールする

コマンドライン ウィンドウで、次の操作を行います。

  1. 次のコマンドを入力して、Express.js フレームワークをインストールします。
    npm install express --save
    

ウェブサーバーを構成する

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 新しい server.js ファイルを作成します。
  3. 次のコードをコピーして貼り付けます。
    const express = require("express");
    const path = require("path");
    
    // Running PORT is set automatically by App Engine
    const port = process.env.PORT || 3000;
    const app = express();
    
    const publicPath = path.join(__dirname, "/dist/photo-gallery-app");
    
    app.use(express.static(publicPath));
    
    app.get("*", (req, res) => {
      res.sendFile(path.join(__dirname + "/dist/photo-gallery-app/index.html"));
    });
    
    app.listen(port, () => {
      console.log(`Server is up on ${port}`);
    });
    
  4. server.js ファイルを保存します。

ウェブサーバーをアタッチする

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. package.json ファイルを開きます。
  3. server.js ファイルでノードを実行するように start コマンドを変更します。
    "name": "photo-gallery-app",
      "version": "0.0.0",
      "scripts": {
        "ng": "ng",
        "start": "node server.js",
        "build": "ng build",
        "watch": "ng build --watch --configuration development",
        "test": "ng test"
      },
    
    start 属性は、アプリケーションのエントリ ポイントです。
  4. package.json ファイルを保存します。

App Engine を構成する

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 新しい app.yaml ファイルを作成します。
  3. 次のコードをコピーして貼り付けます。
    runtime: nodejs16
    service: default
    
    app.yaml ファイルの情報には、App Engine の構成が指定されます。指定する必要があるのはランタイムとサービスのみです。
  4. app.yaml ファイルを保存します。

gcloud 無視リストを更新する

node_modules ディレクトリがアップロードされないようにするには、.gcloudignore ファイルを作成します。.gcloudignore ファイルにリストされているファイルはアップロードされません。

コードエディタで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 新しい .gcloudignore ファイルを作成します。
  3. 次のコードをコピーして貼り付けます。
    # This file specifies files that are *not* uploaded to Google Cloud
    # using gcloud. It follows the same syntax as .gitignore, with the addition of
    # "#!include" directives (which insert the entries of the given .gitignore-style
    # file at that point).
    #
    # For more information, run:
    #   $ gcloud topic gcloudignore
    #
    .gcloudignore
    # If you would like to upload your .git directory, .gitignore file or files
    # from your .gitignore file, remove the corresponding line
    # below:
    .git
    .gitignore
    
    # Node.js dependencies:
    node_modules/
    
  4. .gcloudignore ファイルを保存します。

アプリケーションを初期化する

アプリケーションをデプロイする前に、プロジェクトでそれを初期化し、関連するリージョンを選択します。

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次のコマンドを入力して、アプリケーションを初期化します。
    gcloud app create --project=[YOUR_PROJECT_ID]
    
  3. プロンプトが表示されたら、App Engine アプリケーションを配置するリージョンを選択します。

アプリケーションをデプロイする

コマンドライン ウィンドウで、次の操作を行います。

  1. 新しい photo-gallery-app プロジェクト ディレクトリに移動します。
  2. 次のコマンドを入力して、アプリケーションをデプロイします。
    gcloud app deploy --project=[YOUR_PROJECT_ID]
    
  3. プロンプトが表示されたら、アクションを確認します。gcloud デプロイ コマンドが正常に完了すると、アプリケーションにアクセスするための URL が表示されます。
  4. 次のコマンドを入力して、ブラウザで新しいタブを開きます。
    gcloud app browse
    
    gcloud app deploy のコンソール出力と glcoud app browse への入力

11. 完了

これで操作は完了です。Angular v14 を使用してサンプルのフォトギャラリーを作成し、App Engine に正常にデプロイしました。

スタンドアロンのコンポーネント機能と遅延読み込みを試しました。フィードバックやコメントを提供するためのフォームベースの送信メッセージ機能を作成しました。また、Dialogflow Messenger を使用して Dialogflow CX 仮想エージェントとのチャット ダイアログを正常に追加しました。よくできました。

次のステップ

基本的なアプリが完成したので、次のアイデアを使用してアプリを改善しましょう。

  • フォームは実際にはフィードバックを送信しません。メールを送信するビジネス ロジックを追加するようにリファクタリングします。
  • 実際のシナリオでは、ユーザー入力を検証し、ボットのスパムを回避するために、文字入力による認証などのメカニズムを含める必要があります。
  • 新しいエージェントを作成し、Dialogflow CX で会話フローを設計する方法を学習する

Angular フレームワークをさらに試して、楽しみましょう。

Cloud プロジェクトをクリーンアップして削除する

Cloud プロジェクトは、保持することも、削除してプロジェクトで使用しているすべてのリソースに対する課金を停止することもできます。

ブラウザで次の操作を行います。

  1. Gmail または Google Workspace アカウントにログインします。
  2. Google Cloud コンソールで、[IAM と管理] ボタンを選択します。
  3. [IAM と管理] ページで、[リソースの管理] タブを選択します。
  4. [リソースの管理] ページで、削除するプロジェクトに移動して選択します。[削除] ボタンを選択してダイアログ ウィンドウを開きます。
  5. ダイアログ ウィンドウでプロジェクト ID を入力し、[シャットダウン] ボタンを選択してプロジェクトを削除します。