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

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
    
    次の表に、コマンドの各部分を示します。

    Part

    詳細

    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 デベロッパー ツールのパネルが開いているアプリのスクリーンショット
  4. [Find out more about these guys!] ボタンを選択して、スタンドアロン コンポーネントに移動します。ログには、完全なルーターにアクセスしたときにのみコンポーネントが読み込まれることが示されます。リストの最後までスクロールして、コンポーネントが読み込まれたことを確認します。画面は次のスクリーンショットのようになっているはずです。遅延読み込みされたコンポーネントを示す Chrome DevTools パネルが開いているアプリのスクリーンショット

6. フォームの UI を追加します。

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

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

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 要素によって発行された submit イベントをリッスンします。次に、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. [Full Name](フルネーム)、[Email](メールアドレス)、[Comments](コメント)の各テキスト ボックスに任意の値を入力します。
  4. [送信] ボタンを選択します。ページに成功メッセージが表示されます。
  5. [コンソール] タブに値が表示されていることを確認します。画面は次のスクリーンショットと一致しているはずです。フォームに入力された JSON データを表示するコンソールを含むブラウザ ウィンドウコンポーネント UI に [メッセージを送信] フォームを追加し、ユーザー入力を解析するコードを実装できました。
  6. 次に、チャット ダイアログを埋め込んで、アプリケーションの訪問者が Jimbo と会話できるようにします。Jimbo はコアラで、野生動物に関する興味深い情報を教えてくれます。

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

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

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

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

コンポーネントに 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 エージェントの一意の識別子を指定します。

    chat-title

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

    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 コンソールで課金を有効にすると、Cloud のリソースと API を使用できるようになります。詳細については、セルフサービスの Cloud 請求先アカウントの作成、変更、閉鎖をご覧ください。
  3. App Engine アプリケーション リソースと他の Google Cloud リソースを保持する Google Cloud プロジェクトを作成します。詳細については、プロジェクトの作成と管理をご覧ください。
  4. Cloud Console で 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 ファイルでノードを実行するように、開始コマンドを変更します。
    "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 仮想エージェントとのチャット ダイアログを追加することにも成功しました。よくできました。

次のステップ

基本的なアプリケーションが完成したので、次のアイデアを使用して改善します。

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

Angular フレームワークを使い続けて、楽しんでください。

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

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

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

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