Angular 6チュートリアル:新しいパワーを備えた新機能

公開: 2022-03-11

Angular 6がリリースされました! 最も顕著な変更は、CLIとサービスの注入方法にあります。 このチュートリアルで最初のAngular6アプリ(またはAngular / Firebaseアプリ)を作成する場合は、初期設定の基本的な手順を確認し、小さな日記アプリを作成します。

Angular 6:基本

これまでAngularを使用したことがない場合は、Angularの簡単な説明とその仕組みを説明します。

Angularは、デスクトップとモバイルの両方のシングルページアプリケーション(SPA)の構築をサポートするように設計されたJavaScriptフレームワークです。

フレームワークには、ナビゲーション、承認、フォーム、レポートなど、Webアプリの最も一般的なシナリオのいくつかを簡単に実装できるようにするディレクティブとモジュールの完全なスイートが含まれています。 また、Jasmineフレームワークを使用してテストを追加し、KarmaまたはProtractorテストランナーを使用してテストを実行するために必要なすべてのパッケージが付属しています。

Angularアーキテクチャは、コンポーネント、テンプレート、ディレクティブ、およびサービスに基づいています。 これは、サービスに組み込まれた依存性注入メカニズムと、ビューをコンポーネントコードに接続するための双方向のデータバインディングを提供します。

AngularはJSの型付きスーパーセットであるTypeScriptを使用しており、特に型付き言語のバックグラウンドを持っている場合は、いくつかのことが簡単になります。

Angular 6:新機能

Angular 6の新機能の概要:

  • フレームワークパッケージ( @angular/core@angular/common@angular/compilerなど)、CLI、Material、およびCDKのメジャーバージョン番号を同期するポリシー。 これにより、今後の相互互換性がより明確になります。バージョン番号を一目見れば、主要なパッケージが相互に互換性があるかどうかがわかります。
  • 新しいngコマンド:
    • パッケージバージョンをスマートにアップグレードするためのng update 、依存関係バージョンの更新、およびそれらの同期の維持。 (たとえば、 ng update @angular/coreを実行すると、すべてのフレームワークとRxJSが更新されます。)パッケージに回路が含まれている場合は、回路も実行されます。 (新しいバージョンにコードの変更を必要とする重大な変更が含まれている場合、回路図面はコードを更新します。)
    • ng addを使用して新しいパッケージを追加します(該当する場合はスクリプトを実行します)
  • サービスは、以前のようにサービスを参照するモジュールではなく、サービスを提供するモジュールを参照するようになりました。

この最後の変更の意味の例として、コードは次のようになりました。

 @NgModule({ // ... providers: [MyService] })

…Angular6のこの特定の変更により、次のようになります。

 @Injectabe({ providedIn: 'root', })

これらはツリーシェイク可能プロバイダーと呼ばれ、コンパイラーが参照されていないサービスを削除できるようにして、バンドルのサイズを小さくします。

Angular 6 CLI

ngコマンドラインインターフェースはAngularの非常に重要な部分であり、アプリをコーディングするときに高速に移動できます。

CLIを使用すると、アプリの初期設定を非常に簡単にスキャフォールディングし、新しいコンポーネントやディレクティブなどを生成し、ローカル環境でアプリをビルドして実行できます。

Angular6プロジェクトの作成

さて、十分な話。 手を汚してコーディングを始めましょう。

開始するには、Node.jsとnpmがマシンにインストールされている必要があります。

それでは、CLIをインストールしてみましょう。

 npm install -g @angular/cli

これにより、 -gスイッチにより、 ngコマンドがグローバルにインストールされます。

それができたら、 ng newを使用してアプリの最初のスキャフォールドを取得できます。

 ng new my-memories --style=scss

これにより、 my-memoriesフォルダーが作成され、初期セットアップを開始するために必要なすべてのファイルが作成され、必要なすべてのパッケージがインストールされます。 --style=scssスイッチはオプションであり、SCSSファイルをCSSにコンパイルするようにコンパイラーをセットアップします。これは後で必要になります。

インストールが完了すると、 cd my-memoriesして、 ng serveを実行できます。 これにより、ビルドプロセスと、 http://localhost:4200でアプリを提供するローカルウェブサーバーが開始されます。

足場直後のAngular6アプリ

舞台裏で起こっていることは、CLIがすべての.ts (TypeScriptファイル)をバニラJSに変換し、パッケージフォルダーnode_modulesから必要なすべての依存関係を収集し、ローカルWebサーバーを介して提供される一連のファイルに結果を出力することです。ポート4200で実行されます。

プロジェクトファイル

Angularのプロジェクトフォルダー構造に精通していない場合、知っておく必要がある最も重要なことは、アプリに関連するすべてのコードがsrcフォルダー内にあることです。 通常、アプリアーキテクチャ(ユーザー、カート、製品など)に従って、そのフォルダーにすべてのモジュールとディレクティブを作成します。

Angular6プロジェクトのフォルダー構造

初期設定

これで、アプリの初期設定が完了しました。 いくつかの変更を始めましょう。

始める前に、 srcフォルダーを少し掘り下げてみましょう。 最初のページはindex.htmlです:

 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>MyMemories</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-root></app-root> </body> </html>

ここに、いくつかの基本的なHTMLと<app-root>タグがあります。 これはAngularコンポーネントであり、Angular6がコンポーネントコードを挿入します。

app/app.component.tsファイルが見つかります。このファイルには、 index.htmlファイルの内容と一致するセレクターapp-rootがあります。

コンポーネントは装飾されたTypeScriptクラスであり、この場合、 titleプロパティが含まれています。 @Componentデコレータは、コンポーネントの動作をクラスに含めるようにAngularに指示します。 セレクターに加えて、レンダリングするHTMLファイルと使用するスタイルシートを指定します。

 import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { title = 'app'; }

app.component.htmlを見ると、 {{title}}補間バインディングが表示されます。 ここですべての魔法のバインディングが発生し、Angularはクラスtitleプロパティの値をレンダリングし、変更されるたびに更新します。

 <!--The content below is only a placeholder and can be replaced.--> <div> <h1> Welcome to {{ title }}! </h1> <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="> </div> <h2>Here are some links to help you start: </h2> <ul> <li> <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2> </li> <li> <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2> </li> <li> <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2> </li> </ul>

さあ、クラスのtitle'My Memories!'に更新しましょう。 。

 ... export class AppComponent { title = 'My Memories!'; } ...

コンパイラが変更を処理し、ブラウザが更新されて更新されたタイトルが表示されます。

これは、Angular6のng serveがファイルの変更を監視し、変更がファイルに導入されるたびにレンダリングすることを意味します。

コーディングをより使いやすくし、変更を加えるたびにページ全体が更新されないようにするために、変更されたJS / CSSのチャンクを更新するだけで、変更されたJS / CSSのチャンクを更新するwebpackホットモジュール置換(HMR)を利用できます。変更を表示します。

HMRの構成

まず、環境を整える必要があります。

次の内容のファイルsrc/environments/environment.hmr.tsを作成します。

 export const environment = { production: false, hmr: true };

src/environments/environment.prod.tsを更新し、 hmr: falseフラグを環境に追加します。

 export const environment = { production: true, hmr: false };

次に、 src/environments/environment.tsを更新し、そこの環境にもhmr: falseフラグを追加します。

 export const environment = { production: false, hmr: false };

次に、 angular.jsonファイルで、この部分を更新します。

 "projects": { "my-memories": { // ... "architect": { "build": { // ... "configurations": { "hmr":{ "fileReplacements":[ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.hmr.ts" } ] }, // ...

そして、 projectsmy-memoriesarchitectserveconfigurationsの下で:

 "projects": { "my-memories": { "architect": { // ... "serve": { // ... "configurations": { "hmr": { "browserTarget": "my-memories:build:hmr" }, // ...

ここで、 tsconfig.app.jsonを更新して、 compilerOptionsの下にこれを追加することにより、必要なtypes (まあ、タイプ)を含めます。

 "compilerOptions": { // ... "types": [ "node" ]

次に、 @angularclass/hmrモジュールを開発依存関係としてインストールします。

 npm install --save-dev @angularclass/hmr

次に、ファイルsrc/hmr.tsを作成して構成します。

 import { NgModuleRef, ApplicationRef } from '@angular/core'; import { createNewHosts } from '@angularclass/hmr'; export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => { let ngModule: NgModuleRef<any>; module.hot.accept(); bootstrap().then(mod => ngModule = mod); module.hot.dispose(() => { const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef); const elements = appRef.components.map(c => c.location.nativeElement); const makeVisible = createNewHosts(elements); ngModule.destroy(); makeVisible(); }); };

次に、上記の関数を使用するようにsrc/main.tsを更新します。

 import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; import { hmrBootstrap } from './hmr'; if (environment.production) { enableProdMode(); } const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); if (environment.hmr) { if (module[ 'hot' ]) { hmrBootstrap(module, bootstrap); } else { console.error('HMR is not enabled for webpack-dev-server!'); console.log('Are you using the --hmr flag for ng serve?'); } } else { bootstrap().catch(err => console.log(err)); }

ここで行っているのは、ブートストラップに無名関数を呼び出させ、次にenvironment.hmrフラグがtrueかどうかを確認することです。 そうである場合は、ホットモジュール交換を有効にしたhmr.tsから以前に定義された関数を呼び出します。 それ以外の場合は、以前と同じようにブートストラップします。

これで、 ng serve --hmr --configuration=hmrを実行すると、 hmr構成が呼び出され、ファイルに変更を加えると、完全に更新せずに更新が取得されます。 最初の--hmrはwebpack用であり、-configuration --configuration=hmrはAngularがhmr環境を使用するためのものです。

プログレッシブウェブアプリ(PWA)

Angular 6 PWAサポートを追加し、アプリのオフライン読み込みを有効にするために、新しいCLIコマンドの1つであるng add :を利用できます。

 ng add @angular/[email protected]

このチュートリアルを書いているときの最新バージョンがエラーをスローしていたので、バージョンを追加していることに注意してください。 (それなしで試して、単にng add @angular/pwaを使用して、それが機能するかどうかを確認できます。)

さて、コマンドを実行した後、プロジェクトに多くの変更が表示されます。 最も重要な変更は、次のことを追加したことです。

  • angular.jsonアセットファイル内のmanifest.jsonへの参照。これは、ビルド出力と"serviceWorker": true
  • アプリの実行に必要なすべてのファイルをキャッシュするための初期設定をngsw-config.jsonファイル
  • index.htmlファイルのmanifest.jsonメタタグ
  • アプリの基本構成を含むmanifest.jsonファイル自体
  • アプリモジュールServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })でのService Workerの読み込み(Service Workerは本番環境でのみ有効になることに注意してください)

つまり、これは、ユーザーが最初にURLにアクセスしたときに、ファイルがダウンロードされることを意味します。 その後、ユーザーがネットワークサービスなしでURLにアクセスしようとしても、アプリはそれらのキャッシュされたファイルをプルすることで機能します。

Material Angular6UIライブラリの追加

これで初期設定が完了し、アプリの作成を開始する準備が整いました。 すでに構築されているコンポーネントを利用するために、Angular6バージョンのMaterialを使用できます。

私たちのアプリにmaterialパッケージをインストールするために、再びng addを利用します:

 ng add @angular/material

それを実行すると、いくつかの新しいパッケージが追加され、いくつかの基本的なスタイル構成が表示されます。

  • index.htmlには、Robotoフォントとマテリアルアイコンが含まれています
  • BrowserAnimationsModuleAppModuleに追加されました
  • angular.jsonには、インディゴピンクのテーマがすでに含まれています

ビルド済みのAngular6テーマの選択を示します

テーマを取得するには、 ng serveを再起動する必要があります。または、別のビルド済みテーマを選択することもできます。

関連: Angularマテリアルを使用して超近代的なWebアプリを構築する

基本レイアウト

初期のサイドナビゲーションレイアウトを作成するには、Materialに付属の回路図を使用します。 ただし、別のレイアウトを使用する場合は問題ありません。

(簡単に言うと、回路図面を使用すると、プロジェクトに変換を適用できます。必要に応じてファイルを作成、変更、または削除できます。この場合、アプリのサイドナビゲーションレイアウトの足場になります。)

 ng generate @angular/material:material-nav --name=my-nav

これにより、最小限のセットアップを開始する準備ができたsidenavコンポーネントが作成されます。 それは素晴らしいことではありませんか?

また、 app.module.tsに必要なすべてのモジュールが含まれています。

新しく作成された「my-nav」Angular6コンポーネント

SCSSを使用しているため、 my-nav.component.cssファイルの名前をmy-nav.component.scss -nav.component.scssに変更し、my my-nav.component.ts nav.component.tsで対応する参照styleUrlsを更新して新しい名前を使用する必要があります。

新しいコンポーネントを利用するために、 app.component.htmlに移動して、最初のコードをすべて削除し、次のコードだけを残します。

 <app-my-nav></app-my-nav>

ブラウザに戻ると、次のように表示されます。

左上隅にメニューがあり、その横にmy-memoriesがあり、メニューの下に3つの番号付きリンクがある4ペインのレイアウト。 4番目のペインは空です

リンクを更新して、必要な2つのオプションだけを追加しましょう。

まず、2つの新しいコンポーネントを作成しましょう。

 ng gc AddMemory ng generate @angular/material:material-table --name=view-memories

(2つ目は、テーブルの作成に使用される材料回路図です。)

次に、 my-navで更新してリンクを設定し、コンテンツコンポーネントを表示する<router-outlet>を含めます。

 <mat-sidenav-container class="sidenav-container"> <mat-sidenav #drawer class="sidenav" fixedInViewport="true" [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'" [mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)"> <mat-toolbar color="primary">Menu</mat-toolbar> <mat-nav-list> <a mat-list-item [routerLink]="['/add-memory']">Add Memory</a> <a mat-list-item [routerLink]="['/view-memories']">View My Memories</a> </mat-nav-list> </mat-sidenav> <mat-sidenav-content> <mat-toolbar color="primary"> <button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()" *ngIf="isHandset$ | async"> <mat-icon aria-label="Side nav toggle icon">menu</mat-icon> </button> <span>my-memories</span> </mat-toolbar> <router-outlet></router-outlet> </mat-sidenav-content> </mat-sidenav-container>

また、 app.component.htmlでは、メインの<router-outlet>だけを持つように更新する必要があります(つまり、 <my-nav>を削除します)。

 <router-outlet></router-outlet>

次に、 AppModuleにルートを含めます。

 import { RouterModule, Routes } from '@angular/router'; // ... imports: [ // ... RouterModule.forRoot([ { path: '', component: MyNavComponent, children: [ { path: 'add-memory', component: AddMemoryComponent }, { path: 'view-memories', component: ViewMemoriesComponent } ] }, ]), ]

MyNavComponentを親として設定し、2つのコンポーネントを子として設定していることに注意してください。 これは、 MyNavComponent<router-outlet>を含め、これら2つのルートのいずれかにヒットするたびに、 <router-outlet>が配置された子コンポーネントをレンダリングするためです。

この後、アプリを提供すると、次のように表示されます。

左側のリンクは、[メモリの追加]と[マイメモリの表示]に置き換えられ、後者が選択されています。空のペインには、ID番号と名前のテーブルがあります。

アプリを作成する(思い出の日記)

では、新しい思い出を日記に保存するためのフォームを作成しましょう。

いくつかのマテリアルモジュールとフォームモジュールをapp.module.tsにインポートする必要があります。

 import { FormsModule } from '@angular/forms'; import { MatCardModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, MatNativeDateModule } from '@angular/material'; // ... Imports:[ // ... MatCardModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, FormsModule, MatNativeDateModule, // ... ]

次に、 add-memory.component.htmlに次のフォームを追加します。

 <form #form="ngForm" (ngSubmit)="onSubmit()"> <mat-card class="memory-card"> <mat-card-title> Add a memory </mat-card-title> <mat-card-content> <mat-form-field> <input disabled matInput placeholder="Select the date..." [(ngModel)]="memory.date" name="date" [matDatepicker]="date"> <mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle> <mat-datepicker disabled="false" #date></mat-datepicker> </mat-form-field> <mat-form-field> <textarea placeholder="Enter your memory..." rows="3" maxlength="300" matInput [(ngModel)]="memory.text" name="memory"></textarea> </mat-form-field> </mat-card-content> <mat-card-actions> <button mat-button type="submit">Save me!</button> </mat-card-actions> </mat-card> </form> <pre> {{ memory | json }} </pre>

ここでは、 mat-cardを使用し、 datetextareaの2つのフィールドを追加しています。

[(ngModel)]を使用していることに注意してください。 このAngularディレクティブは、後で説明するように、クラス内のmemory.date式とmemoryプロパティを相互にバインドします。 ( [(ngModel)]はシンタックスシュガーです。クラスからビューへ、およびビューからクラスへの双方向のデータバインディングを実行するためのショートカットです。つまり、ビューにテキストを入力すると、 memory.dateはそれらの変更を反映します。クラスインスタンスで、クラスインスタンスでmemory.dateに変更を加えると、ビューに変更が反映されます。)

add-memory.component.tsでは、コードは次のようになります。

 import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-add-memory', templateUrl: './add-memory.component.html', styleUrls: ['./add-memory.component.scss'] }) export class AddMemoryComponent implements OnInit { memory: any = {}; constructor() { } ngOnInit() { } onSubmit() { console.log(this.memory); } }

ここでは、 ngModelを介してバインドされたmemoryプロパティを初期化しています。 AddMemoryComponentコンポーネントがインスタンス化されると、 memoryは空のオブジェクトになります。 次に、 ngModelディレクティブを実行すると、入力値をmemory.datememory.textに割り当てることができます。 これを行わないCannot set property 'date/text' of undefinedというエラーが発生します。

一方、 add-memory.component.scssには次のものが必要です。

 .memory-card { min-width: 150px; max-width: 400px; width: 100%; margin: auto; } .mat-form-field { width: 100%; }

<pre> {{ memory | json }} </pre> <pre> {{ memory | json }} </pre>ビューでmemoryの現在の状態を確認できます。 ブラウザに移動すると、これまでの結果は次のようになります。

ユーザー入力(日付とテキスト)の内部表現を示す「my-memories」日記アプリのプロトタイプ。

ビューでは、フォームを(ngSubmit)="onSubmit()"経由でクラスのonSubmit関数にバインドしました。

 onSubmit() { console.log(this.memory); }

したがって、「Save me!」をクリックすると、 ボタンをクリックすると、コンソールログに送信されたユーザー入力の内部表現が表示されます。

コンソールログのユーザー入力の内部表現。

Angular 6チュートリアル:Firebaseとの接続

次に行うことは、思い出を保存するためにプロジェクトをFirebaseに接続することです。

まず、Firebaseコンソールに移動して、そこでプロジェクトを作成します。

Firebaseプロジェクトを追加します。

次に、 firebaseパッケージとangularfire2パッケージをインストールします。

 npm install firebase angularfire2 --save

そして、これら3つのファイルのそれぞれで:

  1. /src/environments/environment.ts
  2. /src/environments/environment.hmr.ts
  3. /src/environments/environment.prod.ts

…Firebase設定を追加します:

 export const environment = { // ... firebase: { apiKey: '<your-key>', authDomain: '<your-project-authdomain>', databaseURL: '<your-database-URL>', projectId: '<your-project-id>', storageBucket: '<your-storage-bucket>', messagingSenderId: '<your-messaging-sender-id>' } };

プロジェクトの概要ページで[Firebaseをウェブアプリに追加]をクリックすると、上記のファイルに必要な構成の詳細を取得できます。

その後、Firebaseモジュールをapp.module.tsに含めます。

 import { AngularFireModule } from 'angularfire2'; import { AngularFireDatabaseModule } from 'angularfire2/database'; import { environment } from '../environments/environment'; // ... Imports:[ // ... AngularFireModule.initializeApp(environment.firebase), AngularFireDatabaseModule, // ... ]

また、 add-memory.component.tsでは、コンストラクターにデータベースを挿入し、フォームからデータベースに値を保存します。 Firebaseからのプッシュプロミスが成功すると、コンソールに成功を記録し、モデルをリセットします。

 import { AngularFireDatabase } from 'angularfire2/database'; // ... constructor(private db: AngularFireDatabase) { } // ... onSubmit() { this.memory.date = new Date(this.memory.date).valueOf(); this.db.list('memories').push(this.memory) .then(_ => { this.memory = {} console.log('success') }) } 

Firebaseデータベースへの読み取りおよび書き込みアクセスを許可します。

匿名ユーザーがデータベースルールの読み取りと書き込みを行えるように、データベースルールへのパブリックアクセスを許可する必要があります。 この設定では、すべてのユーザーがアプリデータを読み取ったり、変更したり、削除したりできることに注意してください。 本番環境に移行する前に、それに応じてルールを設定してください。

また、環境の変化を検出するには、 ng serveプロセスを再起動する必要があります。

ここで、ブラウザに戻って[保存]ボタンをクリックすると、メモリがデータベースに追加されたことがわかります。

日記アプリのFirebaseデータベースにテストメモリが追加されました。

思い出を取得してマテリアルテーブルに表示する方法を見てみましょう。

ng generate @angular/material:material-table --name=view-memories', we automatically got a file 。 このファイルには偽のデータが含まれているため、Firebaseからのプルを開始するにはファイルを変更する必要があります。

view-memories-datasource.tsで、 EXAMPLE_DATAを削除し、空の配列を設定します。

 export class ViewMemoriesDataSource extends DataSource<ViewMemoriesItem> { data: ViewMemoriesItem[] = []; // ...

そして、 getSortedDataで、フィールド名を更新します。

 private getSortedData(data: ViewMemoriesItem[]) { if (!this.sort.active || this.sort.direction === '') { return data; } return data.sort((a, b) => { const isAsc = this.sort.direction === 'asc'; switch (this.sort.active) { case 'text': return compare(a.name, b.name, isAsc); case 'date': return compare(+a.id, +b.id, isAsc); default: return 0; } }); }

view-memories.component.htmlで、列の名前をメモリモデルのdatetextに更新します。 日付をミリ秒形式で保存したため、ここでは日付パイプを使用して、表示する値をより人間にわかりやすい日付形式に変換していることに注意してください。 最後に、Firebaseから非同期でデータを読み込むため、ページネーターから[length]="dataSource.data.length"を削除します。

 <div class="mat-elevation-z8"> <table mat-table #table [dataSource]="dataSource" matSort aria-label="Elements"> <!-- Id Column --> <ng-container matColumnDef="date"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th> <td mat-cell *matCellDef="let row">{{row.date | date:'short'}}</td> </ng-container> <!-- Name Column --> <ng-container matColumnDef="text"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Text</th> <td mat-cell *matCellDef="let row">{{row.text}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> <mat-paginator #paginator [pageIndex]="0" [pageSize]="50" [pageSizeOptions]="[25, 50, 100, 250]"> </mat-paginator> </div>

view-memories.component.cssview-memories.component.scss memories.component.scssに変更し、テーブルスタイルを設定します。

 table{ width: 100%; }

view-memories.component.tsで、上記の名前変更をstyleUrlsに反映するように./view-memories.component.scssを変更します。 また、 displayedColumns配列を['date', 'text']に更新し、Firebaseからデータを取得するようにテーブルデータソースを設定します。

ここで行われているのは、メモリリストをサブスクライブしていることです。データを受信すると、 ViewMemoriesDataSourceをインスタンス化し、Firebaseからのデータを使用してそのデータプロパティを設定します。

 this.subscription = this.db.list<ViewMemoriesItem>('memories').valueChanges().subscribe(d=>{ console.log('data streaming'); this.dataSource = new ViewMemoriesDataSource(this.paginator, this.sort); this.dataSource.data = d; });

Firebaseは、ReactiveXスタイルのObservable配列を返します。

this.db.list<ViewMemoriesItem>('memories')'memories'パスから取得された値)をViewMemoriesItemにキャストしていることに注意してください。 これは、 angularfire2ライブラリによって処理されます。

また、AngularコンポーネントライフサイクルのonDestroyフック内にunsubscribe呼び出しを含めました。

 import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; import { MatPaginator, MatSort } from '@angular/material'; import { ViewMemoriesDataSource, ViewMemoriesItem } from './view-memories-datasource'; import { AngularFireDatabase } from 'angularfire2/database'; import { Subscription } from 'rxjs'; import { map, first } from 'rxjs/operators'; @Component({ selector: 'app-view-memories', templateUrl: './view-memories.component.html', styleUrls: ['./view-memories.component.scss'] }) export class ViewMemoriesComponent implements OnInit, OnDestroy{ @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; dataSource: ViewMemoriesDataSource; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['date', 'text']; subscription: Subscription; constructor(private db: AngularFireDatabase) { } ngOnInit() { this.subscription = this.db.list<ViewMemoriesItem>('memories').valueChanges().subscribe(d=>{ console.log('data streaming'); this.dataSource = new ViewMemoriesDataSource(this.paginator, this.sort); this.dataSource.data = d; }); } ngOnDestroy(): void { this.subscription.unsubscribe(); } }
関連:リアルタイムのマルチプラットフォームモバイルアプリケーションの構築:IonicFrameworkとFirebaseを使用した例

FirebaseHostingへのデプロイ

それでは、アプリを公開するために、FirebaseHostingにデプロイしましょう。 そのために、FirebaseCLIをインストールします。これによりfirebaseコマンドが利用可能になります。

 npm install -g firebase-tools

これで、FirebaseCLIを使用してログインできます。

 firebase login

これにより、Googleアカウントを選択するように求められます。

次に、プロジェクトを初期化し、FirebaseHostingを設定します。

 firebase init

ホスティングオプションを選択するだけです。

次に、パスを尋ねられたら、 dist/my-memoriesに設定します。 シングルページアプリとして構成するかどうか(つまり、すべてのURLを/index.htmlに書き換える)を尋ねられたら、「はい」と答えます。

最後に、「File dist / my-memories/index.htmlはすでに存在します。 上書きしますか?」 ここでは「いいえ」と言います。

これにより、提供された構成でFirebase構成ファイル.firebasercfirebase.jsonが作成されます。

最後のステップは実行することです:

 ng build --prod firebase deploy

これで、アプリをFirebaseに公開します。このアプリは、https://my-memories-b4c52.firebaseapp.com/view-memoriesのように、移動先のURLを提供します。デモ。


うわー、あなたはチュートリアルを終えました! 楽しんでいただけたでしょうか。 GitHubで完全なコードを確認することもできます。

一歩ずつ

Angularは、Webアプリを構築するための非常に強力なフレームワークです。 それは長い間存在しており、小さくて単純なアプリでも大きくて複雑なアプリでも同様に証明されています。Angular6も例外ではありません。

今後、Angularは、Webコンポーネント(Angular Elements)などの新しいWebパラダイムを改善し、それに従うことを計画しています。 ハイブリッドアプリの構築に興味がある場合は、基盤となるフレームワークとしてAngularを使用するIonicを確認できます。

このチュートリアルでは、Angular、Material、Firebaseの使用を開始するための非常に基本的な手順について説明しました。 ただし、実際のアプリケーションの場合は検証を追加する必要があり、アプリケーションの保守とスケーリングを容易にするために、サービスや再利用可能なコンポーネントなどの使用などのベストプラクティスに従う必要があることを考慮に入れる必要があります。 。それは別の記事の主題である必要があります—うまくいけば、これはAngular開発へのあなたの欲求を刺激するのに十分でした!

関連:すべての特典、面倒なし:Angular9チュートリアル