_著者はhttps://www.brightfunds.org/organizations/npower-inc[NPower]を選択して、https://do.co/w4do-cta [Write for DOnations]プログラムの一環として寄付を受け取りました。

前書き

https://angular.io [Angular]は、Googleによって構築されたフロントエンドWebフレームワークです。 開発者は、モデルビューコントローラー(MVC)またはモデルビュービューモデル(MVVM)のソフトウェアアーキテクチャパターンを中心にモデル化された単一ページのアプリケーションを構築できます。 このアーキテクチャは、アプリケーションを異なるが接続された部分に分割し、並行開発を可能にします。 このパターンに従って、AngularはそのさまざまなコンポーネントをWebアプリケーションの各部分に分割します。 そのコンポーネントは、そのコンポーネントに関連するデータとロジックを管理し、それぞれのビューにデータを表示し、アプリの他の部分から受信するさまざまなメッセージに基づいてビューを調整または制御します。

Bootstrapは、開発者がレスポンシブWebサイト(さまざまなデバイスに適応するサイト)を迅速かつ効果的に構築するのに役立つフロントエンドライブラリです。 各ページを12列に分割するグリッドシステムを使用して、ページがどのデバイスで表示されていても正しいサイズとスケールを維持できるようにします。

https://www.apixu.com [APIXU]は、APIを介してユーザーにグローバルな気象データを提供します。 APIXUを使用すると、ユーザーは世界のあらゆる場所の最新の天気予報と将来の天気予報を取得できます。

このチュートリアルでは、Angular、Bootstrap、およびAPIXU APIを使用して天気アプリを作成します。 検索フォームに場所を入力し、そのフォームを送信すると、その場所の現在の天気の詳細がアプリに表示されます。 このチュートリアルで使用されるAngularバージョンは7.2.0で、使用されるBootstrapバージョンは4.2.1です。

前提条件

このチュートリアルを始める前に、次のものが必要です。

  • Node.jsおよびhttps://www.npmjs.com/[npm]がローカルマシンにインストールされています。 これらの両方をhttps://nodejs.org.en/ [Node.js Webサイト]からインストールするか、https://www.digitalocean.com/community/tutorials/how-toでこのチュートリアルを実行できます。 -install-node-js-and-create-a-local-development-environment-on-macos [Node.jsのインストールとローカル開発環境のセットアップ]。

  • APIXU APIキー。 無料のAPIXUアカウントにサインアップして、無料のAPIキーhttps://www.apixu.com/signup.aspx [こちら]を取得します。

  • Visual Studio Code、https://atom.io [Atom]、またはhttps://www.sublimetext.com [Sublime Text]などのインストールされたテキストエディター。

  • JSONとその形式に精通している。 詳細については、https://www.digitalocean.com/community/tutorials/how-to-work-with-json-in-javascript [JavascriptでJSONを使用する方法]をご覧ください。

  • Javascriptの配列を理解するおよびhttps:// wwwで詳しく学ぶことができるJavascriptの配列とオブジェクトの理解。 digitalocean.com/community/tutorials/understanding-data-types-in-javascript#objects[Javascriptのデータ型について]。

手順1-Angularのインストール

アプリの作成を開始する前に、Angularをインストールする必要があります。 端末を開き、次のコマンドを実行して、Angular CLIをマシンにグローバルにインストールします。

npm install -g @angular/cli

Angular CLIは、Angularのコマンドラインインターフェイスです。 これは、新しいAngularプロジェクトとAngularプロジェクトを構成するさまざまなサブ要素を作成する主な方法として機能します。 `+ -g +`引数を使用すると、グローバルにインストールされます。

しばらくすると、次の出力が表示されます。

Angularのインストールからの出力

...
+ @angular/[email protected]
...

これで、Angularがローカルマシンにインストールされました。 次に、Angularアプリケーションを作成します。

ステップ2-Angularアプリの作成

この手順では、新しいAngularアプリケーションを作成および構成し、BootstrapやjQueryなどのすべての依存関係をインストールし、最後にデフォルトのアプリケーションが期待どおりに動作することを確認します。

最初に、 `+ ng +`コマンドを使用してAngularアプリケーションを作成します。これはターミナルから実行できます。

`+ ng `コマンドは、コマンドラインからAngularでアクションを実行するための前提条件です。 たとえば、新しいプロジェクトを作成する場合でも、コンポーネントを作成する場合でも、テストを作成する場合でも、必要な各機能の前に「 ng 」コマンドを付けます。 このチュートリアルでは、新しいアプリケーションを作成します。これを実現するには、「 ng new 」コマンドを実行します。 ` ng new +`コマンドは、新しいAngularアプリケーションを作成し、必要なライブラリをインポートし、アプリケーションが必要とするすべてのデフォルトコードの足場を作成します。

新しいアプリケーションを作成することから始めます。このチュートリアルでは「++」と呼ばれますが、名前は自由に変更できます。

ng new

`+ ng new +`コマンドは、新しいアプリケーションに追加する機能に関する追加情報の入力を求めます。

OutputWould you like to add Angular routing? (y/N)

Angular `+ routing`を使用すると、ルートとコンポーネントを使用して、さまざまなビューを持つ単一ページのアプリケーションを構築できます。 先に進み、「+ y 」と入力するか、「 ENTER +」を押してデフォルトを受け入れます。

OutputWhich stylesheet format would you like to use? (Use arrow keys)

デフォルトのCSSオプションを受け入れるには、「+ ENTER +」を押します。

アプリは作成プロセスを続行し、しばらくすると次のメッセージが表示されます。

Output...
CREATE weather-app/e2e/src/app.e2e-spec.ts (623 bytes)
CREATE weather-app/e2e/src/app.po.ts (204 bytes)
...
Successfully initialized git.

次に、テキストエディターで、「++」フォルダーを開きます。

ディレクトリの構造を見ると、いくつかの異なるフォルダーとファイルが表示されます。 これらのファイルすべてがhttps://angular.io/guide/file-structure [ここ]で何を行うかについての完全な説明を読むことができますが、このチュートリアルの目的のために、これらは理解する最も重要なファイルです。

  • `+ package.json`ファイル。 ルートの「++」フォルダにあり、他のNode.jsアプリケーションと同様に機能し、アプリケーションが使用するすべてのライブラリ、アプリケーションの名前、テスト時に実行するコマンドなどを保持します。 主に、このファイルには、Angularアプリケーションが適切に実行するために必要な外部ライブラリに関する詳細が保持されます。

  • `+ app.module.ts `ファイル。 このファイルは、「 / src」フォルダー内の「+ app」フォルダーにあり、Angularにアプリケーションのアセンブル方法を伝え、アプリケーションのコンポーネント、モジュール、プロバイダーに関する詳細を保持します。 既にインポートされたモジュール `+ BrowserModule `が ` imports `配列内にあります。 ` BrowserModule `は、アプリケーションに不可欠なサービスとディレクティブを提供し、常に ` imports +`配列の最初のインポートモジュールでなければなりません。

  • `+ angular.json`ファイル。 アプリのルート「++」フォルダーにある、これはAngular CLIの構成ファイルです。 このファイルには、Angularアプリケーションの実行に必要な内部構成設定が保持されます。 アプリケーション全体のデフォルトを設定し、テスト時に使用する構成ファイル、アプリで使用するグローバルスタイル、ビルドファイルを出力するフォルダーなどのオプションがあります。 これらのオプションの詳細については、公式のhttps://github.com/angular/angular-cli/wiki/angular-cli[Angular-CLI documentation]をご覧ください。

次にBootstrapをインストールするので、これらのファイルはすべてそのままにしておくことができます。

Bootstrapには、Angularで正しく動作するためにインストールする必要がある2つの依存関係があります-http://jquery.com/[jQuery]とhttps://popper.js.org [popper.js]。 + jQuery`はクライアント側のスクリプトに焦点を合わせたJavaScriptライブラリであり、 + popper.js`は主にツールチップとポップオーバーを管理するポジショニングライブラリです。

ターミナルで、ルートの `++`ディレクトリに移動します。

cd

次に、次のコマンドを実行してすべての依存関係をインストールし、参照を `+ package.json +`ファイルに保存します。

npm install --save jquery popper.js bootstrap

+-save`オプションは、参照を + package.json`ファイルに自動的にインポートするため、インストール後に手動で参照を追加する必要はありません。

次のように、インストールされたバージョン番号を示す出力が表示されます。

これで、Bootstrapとその依存関係が正常にインストールされました。 ただし、これらのライブラリをアプリケーションに含める必要もあります。 あなたの ++`は、これらのライブラリが必要であることをまだ知らないため、 `+ jquery ++ popper.js ++ bootstrap.js +、および + bootstrap.css +へのパスを追加する必要があります。 `を + angular.json + `ファイルに追加します。

`+ popper.js `の場合、含める必要があるファイルは ` node_modules / popper.js / dist / umd / popper.js `です。 jQueryには、 ` node_modules / jquery / dist / jquery.slim.js `ファイルが必要です。 最後に、Bootstrapには2つのファイル(JavaScriptファイルとCSSファイルの両方)が必要です。 これらはそれぞれ ` node_modules / bootstrap / dist / js / bootstrap.js `と ` node_modules / bootstrap / dist / css / bootstrap.css +`です。

必要なファイルパスがすべて揃ったので、テキストエディターで + angular.json`ファイルを開きます。 `+ styles +`配列はCSSファイルへの参照を追加する場所で、 `+ scripts +`配列はすべてのスクリプトを参照します。 これらの配列は両方とも、 `+" options ":+ JSONオブジェクト内の `+ angular.json +`ファイルの上部近くにあります。 次の強調表示されたコンテンツをファイルに追加します。

angular.json

...
"options:" {
...
"styles": [

    "src/styles.css"
],
"scripts": [
   ,
   ,

]},
...

これで、Bootstrapが正常に機能するために必要なメインの + .js`ファイルと + .css`ファイルがインポートされました。 `+ angular.json `ファイルからこれらのファイルへの相対パスを指定しました:スタイル配列に ` .css `ファイルを追加し、 ` angular.json `のスクリプト配列に ` .js `ファイルを追加します。 このコンテンツを追加した後、 ` angular.json`ファイルを保存したことを確認してください。

ここで、 `+ ng serve `コマンドでアプリケーションを起動して、すべてが正常に機能していることを確認します。 ターミナルの「+」ディレクトリから、次を実行します。

ng serve --o

`+-o +`引数は、アプリケーションを表示するブラウザウィンドウを自動的に開きます。 アプリケーションの構築には数秒かかり、ブラウザに表示されます。

端末に次の出力が表示されます。

Output** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
...

ブラウザが開くと、デフォルトのAngularアプリのページが表示されます。

image:https://assets.digitalocean.com/articles/angular_bootstrap/step2.png [Angularでデフォルトで作成されたアプリの画像]

これらの出力が表示されない場合は、この手順をもう一度実行して、すべてが正しいことを確認してください。 次のようなエラーが表示された場合: `+ Port 4200 is already in use。 「–port」を使用して別のポートを指定し、「」を入力してポート番号を変更できます。

ng serve --o --port

この潜在的なエラーメッセージの理由は、マシンのポート「4200」が別のプログラムまたはプロセスによって使用されているためです。 そのプロセスが何かを知っている場合は、それを終了するか、上記の手順に従って別のポート番号を指定できます。

これで、アプリケーションの足場を設定できました。 次に、メインフォームと検索場所の関連する天気の詳細を含む天気コンポーネントを作成します。

ステップ3-天気コンポーネントの作成

Angularアプリケーションは、主に_components_で構成されます。これは、アプリケーション内で特定の機能を持つロジックの一部です。 コンポーネントは、アプリケーションの画面の一部を管理するいくつかの_logic_で構成されます-これは_view_と呼ばれます。

たとえば、このチュートリアルでは、2つのタスクの処理を担当する `+ Weather Component +`を作成します。

  • 場所を検索する

  • その場所に関連する気象データを表示する

最初の目的を達成するために、場所を検索できるフォームを作成します。 フォームの検索ボタンをクリックすると、その場所を検索する機能がトリガーされます。

2番目の目的を達成するために、取得したデータをきれいに表示するネストされた `+ <p> `タグを持つ ` <div> +`を用意します。

端末ウィンドウからアプリを実行している間は、その特定のウィンドウに他のものを入力することはできません。 したがって、他の「+ ng 」コマンドを実行する場合は、新しいターミナルウィンドウで「+」ディレクトリを開きます。 または、 `+ CTRL + C `を押して、元のターミナルウィンドウでアプリの実行を停止できます。 その後、新しいコンポーネントをインストールし、その後「 ng serve –o +」と入力してアプリを再起動できます。

次のコマンドを実行して、 `+ Weather Component `を作成し、それを自動的に ` app.module.ts `ファイルにインポートします。 ` app.module.ts +`ファイルには、アプリケーションのすべてのコンポーネント、モジュール、プロバイダーに関する詳細が保持されていることに注意してください。

ng generate component weather

次のような出力が表示されます(正確なバイトサイズは異なる場合があります)。

OutputCREATE src/app/weather/weather.component.css (0 bytes)
CREATE src/app/weather/weather.component.html (26 bytes)
CREATE src/app/weather/weather.component.spec.ts (635bytes)
CREATE src/app/weather/weather.component.ts (273 bytes)
UPDATE src/app/app.module.ts (400 bytes)
...

この出力は、Angularがコンポーネントに必要な4つのファイルを作成したことを示しています。

  • ビューの + .css`および + .html`ファイル

  • コンポーネントをテストするための `+ .spec.ts +`ファイル

  • コンポーネントの機能を保持する `+ .component.ts +`ファイル

また、Angularは `+ src / app / app.module.ts `ファイルを更新して、新しく作成されたコンポーネントへの参照を追加しました。 コンポーネントファイルは常に ` src / app / +`ディレクトリの下にあります。

新しいコンポーネントをインストールしたので、ブラウザーに戻ってアプリを表示します。 新しいコンポーネントをインストールするために実行中のアプリを停止した場合は、次を入力して再起動します。

ng serve --o

まだページに「アプリへようこそ!」(デフォルトのコンポーネント)が表示されていることがわかります。 新しく作成したコンポーネントは表示されません。 次のセクションでは、これを変更して、「+ localhost:4200+」にアクセスするたびに、Angularのデフォルトコンポーネントではなく、新しく作成された天気コンポーネントにアクセスできるようにします。

ステップ4-天気コンポーネントへのアクセス

標準HTMLでは、新しいページを作成するたびに、新しい `+ .html `ファイルを作成します。 たとえば、新しく作成したページに移動するための既存のHTMLページが既にある場合、その新しいページを指すための ` anchor `タグを持つ ` href +`属性があります。 例えば:

preexisting.html

<a href="/newpage.html">Go to New Page</a>

ただし、Angularでは、これは少し異なります。 この方法で「+ href 」属性を使用して、新しいコンポーネントに移動することはできません。 コンポーネントにリンクする場合、Angularの ` Router +`ライブラリを使用して、コンポーネントに直接マッピングされるファイル内で目的のURLパスを宣言する必要があります。

Angularでは、このファイルを「+ routes.ts 」と呼びます。 これには、ルート(リンク)のすべての詳細が保持されます。 このファイルが正しく機能するためには、 ` @ angular / router `ライブラリから ` Routes `タイプをインポートし、希望のリンクを ` Routes +`タイプにリストします。 これは、これらがアプリ内のナビゲーション用のルートのリストであることをAngularに伝えます。

テキストエディタでファイル `+ routes.ts `を作成し、 ` src / app `ディレクトリに保存します。 次に、次のコンテンツを ` routes.ts +`ファイルに追加します。

src / app / routes.ts

import { Routes } from '@angular/router'

次に、URLパスとコンポーネントを + src / app / routes.ts +`で宣言します。 ホームページ( `+ http:// localhost:4200 +)にアクセスすると、新しく作成したWeatherコンポーネントにアクセスできるようにアプリを作成します。 これらの行をファイルに追加します。これにより、作成したばかりのWeatherコンポーネントにルートURLがマップされます。

src / app / routes.ts

import { Routes } from '@angular/router'

`+ WeatherComponent `をインポートし、タイプ ` Routes `の配列である変数 ` allAppRoutes `を作成しました。 ` allAppRoutes `配列は、それぞれがURLパスとマッピング先のコンポーネントを含むルート定義オブジェクトを保持します。 ルートURL(“)にアクセスするたびに、 ` WeatherComponent +`に移動するように指定しました。

最終的な `+ routes.ts +`ファイルは次のようになります。

src / app / routes.ts

import { Routes } from "@angular/router";
import { WeatherComponent } from "./weather/weather.component";

export const allAppRoutes: Routes = [
 { path: '', component: WeatherComponent }
];

これらのルートをメインの + app.module.ts +`ファイルに追加する必要があります。 作成したばかりの配列( `+ all App Routes)を` + RouterModule`と呼ばれるAngularモジュールに渡す必要があります。 `+ RouterModule `は、ルーター(すべてのアプリナビゲーションの実行を担当)を初期化および構成し、 ` allAppRoutes +`からのルーティングデータを提供します。 次の強調表示されたコンテンツを追加します。

src / app / app.module.ts

...
import {WeatherComponent} from './weather/weather.component';


...
@NgModule({
   declarations:[
     ...
   ],
   imports: [
       BrowserModule,

   ]
   ...
})
...

このファイルでは、ルートオブジェクトの配列「+ RouterModule 」と「 allAppRoutes 」をインポートしました。 次に、 ` allAppRoutes +`配列をRouterModuleに渡して、ルーターがURLのルーティング先を認識できるようにします。

最後に、ルーティング自体を有効にする必要があります。 + app.component.ts +`ファイルを開きます。 特定のコンポーネントのHTMLを指定する `+ templateUrl`プロパティがあります: 。/ app.component.html`。 このファイル ` src / app / app.component.html `を開くと、 ` localhost:4200 +`ページのすべてのHTMLが含まれていることがわかります。

`+ app.component.html`に含まれるすべてのHTMLを削除し、次のものに置き換えます。

src / app / app.component.html

`+ router-outlet `タグはルーティングをアクティブにし、ユーザーがブラウザーに入力するURLを、以前に作成した ` routes.ts `ファイルで ` allAppRoutes `変数の下に作成したルート定義に一致させます。 次に、ルーターはHTMLでビューを表示します。 このチュートリアルでは、 ` <router-outlet> </ router-outlet> `タグの直後に ` weather.component.html`コードを表示します。

これで、 `+ http:// localhost:4200 +`に移動すると、* weather works!*がページに表示されます。

アプリケーションでルーティングを設定しました。 次に、場所を検索して関連する詳細を表示できるフォームと詳細セクションを作成します。

手順5-ユーザーインターフェイスの定義

Bootstrapを使用して、アプリケーションビューの足場として機能します。 ブートストラップは、あらゆるデバイス(モバイル、タブレット、またはデスクトップ)に適合する既製のレスポンシブWebサイトを作成するのに役立ちます。 これは、Webページ上のすべての行を12列幅として扱うことで達成されます。 Webページでは、行はページの一方の端からもう一方の端までの単なる線です。 つまり、すべてのページのコンテンツはその行内に含まれ、12列に等しくなければなりません。 12列に等しくない場合、別の行にプッシュダウンされます。 たとえば、Bootstrapのグリッドシステムでは、12列の行が6列の2つのセクションに分割され、次の12列の行が4列の3つのセクションに分割されます。

Bootstrap documentationで、このグリッドシステムの詳細を読むことができます。

ページを6列の2つのセクションに分割し、左側の列に検索フォームを、右側に天気の詳細を表示します。

+ src / app / weather / weather.component.html +`を開いて、 `+ WeatherComponent + HTMLコードにアクセスします。 現在ファイル内にある段落を削除してから、次のコードを追加します。

src / app / weather / weather.component.html

<div class="container">
 <div class="row">
   <div class="col-md-6"><h3 class="text-center">Search for Weather:</h3></div>
   <div class="col-md-6"><h3 class="text-center">Weather Details:</h3></div>
 </div>
</div>

すべてのコンテンツを保持するために、クラス + container`で + <div> + `を作成しました。 次に、それぞれ6列の2つのセクションに分割する行を作成しました。 左側には検索フォームが、右側には天気データが表示されます。

次に、フォームを作成するために、最初の「+ col-md-6 」列で作業します。 また、フォームに入力した内容をAPIXUに送信するボタンを追加します。APIXUは、要求された天気の詳細を返します。 これを行うには、最初の ` col-md-6 `クラスを特定し、次の強調表示されたコンテンツを ` <h3> +`タグの下に追加します。

src / app / weather / weather.component.html

...
<div class="col-md-6">
 <h3 class="text-center">Search for Weather:</h3>
















...

フォームを追加し、検索バーを保持する `+ form-group`クラスを追加しました。 また、天気を検索するためのボタンを作成しました。 ブラウザでは、天気アプリのページは次のようになります。

image:https://assets.digitalocean.com/articles/angular_bootstrap/step5.png [これまでの天気アプリのページの画像]

これは少しコンパクトに見えるので、CSSを追加してページをより良い間隔でスタイルできます。 Bootstrapの主な利点は、独自のCSSを追加することなくHTMLに追加できるスペーシングクラスが付属していることです。 ただし、Bootstrapの標準クラスがカバーしていない追加のCSSを組み込む場合は、必要に応じて独自のCSSを作成できます。 このチュートリアルでは、Bootstrapの標準クラスを使用します。

すべての + <h3> +`タグに対して、 `+ .my-4 + Bootstrap CSSクラスを追加します。 + m +`は要素にマージンを設定し、 `+ y +`は要素に `+ margin-top +`と `+ margin-bottom +`の両方を設定し、最後に `+ 4 +`は追加するマージンの量を指定します。 さまざまな間隔タイプとサイズの詳細については、https://getbootstrap.com/docs/4.1/utilities/spacing/ [こちら]をご覧ください。 `+ weather.component.html`ファイルで、以下の強調表示されたコンテンツを追加して、現在の + <h3> + `タグを置き換えます。

src / app / weather / weather.component.html

<div class="col-md-6">

 <form>
   <div class="form-group">
     <input
       class="form-control"
       type="text"
       id="weatherLocation"
       aria-describedby="weatherLocation"
       placeholder="Please input a Location"
     />
   </div>
   <div class="text-center">
     <button type="submit" class="btn btn-success btn-md">
       Search for the weather
     </button>
   </div>
 </form>
</div>
<div class="col-md-6">

</div>

ブラウザでページをリロードすると、スペースが増えていることがわかります。

image:https://assets.digitalocean.com/articles/angular_bootstrap/step5b.png [天気アプリに適用される間隔の画像]

フォームと、APIXU APIから受け取った情報を表示するセクションを作成しました。 次に、フォームを接続して、現在地を正しく入力できるようにします。

ステップ6-フォームの配線

Angularには、アプリケーションでのユーザー入力用のフォームを作成する2つの方法があります-reactive_または_template-driven。 同じ結果が得られますが、各フォームタイプはユーザー入力データの処理方法が異なります。

リアクティブフォームでは、 `+ .component.ts `ファイルにフォームのさまざまな要素のリストを作成します。 次に、それらをそれぞれの ` .component.html `ファイル内で作成したHTMLフォームに接続します。 これは厳密に一方向です。つまり、データはHTMLから ` .component.ts +`ファイルに流れ、双方向のデータの流れはありません。

テンプレート駆動フォームでは、通常のHTMLの場合と同じようにフォームを作成します。 次に、「+ ngModel +」などのディレクティブを使用して、HTMLから一方向または双方向のデータバインディングを作成し、コンポーネントのデータモデルに戻したり、その逆を行うことができます。

それぞれのアプローチには長所と短所がありますが、一般的に、次の理由により、リアクティブ形式が望ましいです:

  • さまざまな複雑さのフォームを作成する柔軟性。

  • コンポーネントの `+ .component.ts +`ファイル内の各フォームコントロールの状態をチェックすることにより、単体テストが簡単になります。

  • フォーム内の値を_subscribe_する機能。 開発者は、フォームの値ストリームにサブスクライブして、フォームに入力された値に対してリアルタイムでアクションを実行できます。

これらの長所にもかかわらず、リアクティブフォームは実装がより複雑になる場合があります。 これにより、テンプレート駆動型フォームと比較して、開発者がより多くのコードを記述することになります。 フォームタイプと最適なユースケースの両方の包括的な概要を確認するには、https://angular.io/guide/reactive-forms [Angularの公式ガイド]が出発点として適切です。 このチュートリアルでは、リアクティブフォームを使用します。

リアクティブフォームを使用するには、ファイル「+ app.module.ts 」を開きます。 次に、ファイルの先頭に向かってインポートを宣言して、 ` ReactiveFormsModule +`をインポートします。

src / app / app.module.ts

...

@NgModule({
   ...
})
...

最後に、インポートのリストに `+ ReactiveFormsModule +`を追加します。

src / app / app.module.ts

...
@NgModule({
   ...
   imports: [
       BrowserModule,
       RouterModule.forRoot(allAppRoutes)

   ]
   ...
})
...

これらのコードを追加すると、 `+ app.module.ts +`は次のようになります。

src / app / app.module.ts

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";

import { AppComponent } from "./app.component";
import { WeatherComponent } from "./weather/weather.component";
import { RouterModule } from "@angular/router";
import { allAppRoutes } from "./routes";
import { ReactiveFormsModule } from "@angular/forms";

@NgModule({
 declarations: [AppComponent, WeatherComponent],
 imports: [
   BrowserModule,
   RouterModule.forRoot(allAppRoutes),
   ReactiveFormsModule
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule {}

これらの両方の行を追加したら、 `+ weather.component.ts `ファイルを開き、 ` FormBuilder `クラスと ` FormGroup +`クラスをインポートします。

src / app / weather / weather.component.ts

import { Component, OnInit } from '@angular/core';

次に、 `+ FormGroup `を参照する ` weather.component.ts +`ファイルに変数を作成します。

weather.component.ts

export class WeatherComponent implements OnInit {

  constructor() { }
...

フォームでアクションを実行するたびに、 `+ weatherSearchForm `変数を介して参照します。 コンポーネントで使用できるように、 ` FormBuilder `インポートを ` constructor +`に追加します。

weather.component.ts

...
public weatherSearchForm: FormGroup;
constructor() {}
...

`+ formBuilder `を ` constructor `に追加すると、 ` FormBuilder +`クラスのインスタンスが作成され、コンポーネント内で使用できるようになります。

これで、 `+ FormGroup `とその値を ` weather.component.ts `ファイルに作成する準備ができました。 フォームに複数の入力オプションがある場合は、 ` FormGroup `で囲むことをお勧めします。 このチュートリアルでは、1つ(場所の入力)しかありませんが、練習のためにとにかく ` FormGroup +`を使用します。

コンポーネントに移動するときにフォームを使用する準備ができていることが重要です。 リアクティブフォームを使用しているため、フォームをHTMLにバインドする前に、まずフォーム内に要素のツリーを作成する必要があります。 これを実現するには、 `+ WeatherComponent `内の ` ngOnInit `フックでフォーム要素を作成する必要があります。 ` ngOnInit +`メソッドは、コンポーネントの初期化時に1回実行され、コンポーネントを使用する準備が整う前に実行する必要がある指定したロジックを実行します。

したがって、HTMLプロセスへのバインディングを完了する前に、フォームを作成する必要があります。

`+ WeatherComponent `で、 ` ngOnInit +`フック内でフォームを初期化します:

src / app / weather / weather.component.ts

...
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {



 }

リアクティブフォームスタイルに従ってフォームの最初の部分を作成しました: `+ weather.component.ts `ファイルでフォームコンポーネントを定義します。 フォームの複合要素のグループを作成しました(現時点では、1つの要素、 ` location `があります)。 ` [”] +`配列を使用すると、フォーム入力にいくつかの追加オプションを指定できます。たとえば、データを事前入力し、バリデーターを使用して入力を検証します。 このチュートリアルではこれらのいずれも必要ないため、空白のままにしておくことができます。 要素のプロパティhttps://angular.io/api/forms/FormBuilder[here]に渡すことができるものについて詳しく知ることができます。

フォームが完成する前に、さらに2つの作業が必要です。 最初に、 + weather.component.html`ファイルを開きます。 フォームにプロパティ `+ [formGroup] +`を割り当てる必要があります。 このプロパティは、 `+ weather.component.ts +`ファイルで宣言した変数である `+ weatherSearchForm +`と等しくなります。 次に、 `+ location n`要素( + weather.component.ts`ファイルで宣言)をHTMLにバインドする必要があります。 `+ weather.component.html`で、次の強調表示されたコンテンツを追加します。

src / app / weather / weather.component.html

...
<form
  >
 <div class="form-group">
   <input
     class="form-control"
     type="text"
     id="weatherLocation"
     aria-describedby="weatherLocation"
     placeholder="Please input a Location"
   /> />
 </div>
 <div class="text-center">
   <button type="submit" class="btn btn-success btn-md">
     Search for the weather
   </button>
 </div>
</form>
...

`+ [formGroup] `プロパティを追加して、フォームをHTMLにバインドしました。 また、この特定の ` input `要素が ` weather.component.ts `ファイルの ` location `要素にバインドされることを宣言する ` formControlName +`プロパティを追加しました。

ファイルを保存してブラウザに戻ると、アプリがまったく同じように見えます。 これは、フォームが正しく接続されていることを意味します。 この段階でエラーが発生した場合は、前の手順に戻って、ファイルのすべてが正しいことを確認してください。

次に、入力データをフォームに受け入れることができるようにボタンを接続します。

ステップ7-ボタンの接続

このステップでは、ユーザーの入力データを受け入れることができるように、検索ボタンをフォームに接続します。 また、最終的にユーザーの入力データをAPIXU天気APIに送信するメソッドの足場を作成します。

+ weather.component.html`のコードを振り返ると、ボタンのタイプが + submit`であることがわかります。

src / app / weather / weather.component.html

<form>
...
<div class="text-center">
   <button type="submit" class="btn btn-success btn-md">Search for the weather</button>
</div>
</form>

これは、アクションを実行するためにフォームの値を何らかの関数に送信する標準のHTML値です。

Angularでは、その関数を `(ngSubmit)`イベントで指定します。 フォーム内のボタンをクリックすると、タイプが「+ submit 」である限り、「(ngSubmit)+」イベントがトリガーされ、その後に割り当てられたメソッドが呼び出されます。 この場合、ユーザーが入力した場所を取得し、それをAPIXU APIに送信できるようにします。

まず、これを処理するメソッドを作成します。 `+ weather.component.ts `で、1つの引数(フォームに入力した値)を受け取るメソッド ` sendToAPIXU()+`を作成します。 次の強調表示されたコンテンツをファイルに追加します。

src / app / weather / weather.component.ts

...
ngOnInit() {
   this.weatherSearchForm = this.formBuilder.group({
     location: [""]
   });
 }




...

次に、 `+ ngSubmit `イベントをHTMLに追加し、送信されたフォームの値を ` sendToAPIXU()+`メソッドに渡します。

weather.component.html

...
<form [formGroup]="weatherSearchForm"
 ...
</form>
...

`+ ngSubmit `イベントをフォームに追加し、フォームの送信時に実行するメソッドを接続し、 ` weatherSearchForm `の値をハンドラーメソッドの引数として渡しました( ` weatherSearchForm。値+ `)。 これで、 `+ console.log `を使用して ` formValues `を出力し、 ` sendToAPIXU()`メソッドで次の強調表示されたコンテンツを ` weather.component.ts +`に追加することで、この動作をテストできます。

weather.component.ts

...
sendToAPIXU(formValues){

}

ブラウザに移動して、Webサイトページの任意の場所を右クリックしてコンソールを開き、[要素の検査]をクリックします。 * Console と呼ばれるポップアップウィンドウが表示されます。 フォームに London *と入力します。 [天気を検索]ボタンをクリックすると、現在地が囲まれたオブジェクトが表示されます。

image:https://assets.digitalocean.com/articles/angular_bootstrap/step7.png [sendToAPIXUメソッドの更新後のコンソールからの出力]

コンソールからの出力は、JSONオブジェクト `+ {location:” London “} `です。 ロケーション値にアクセスしたい場合は、 ` formValues.location `にアクセスしてこれを行うことができます。 同様に、フォーム内に他の入力がある場合、 ` .location +`を他の要素名と交換します。

これでボタンが配線され、入力を正しく受け取ることができます。 次に、 `+ sendToAPIXU()+`メソッドにAPIXU APIへのHTTPリクエストを作成させます。

ステップ8-APIXU APIの呼び出し

APIXU APIは位置情報を受け入れ、その位置の現在の天気の詳細を検索し、それらをクライアントに返します。 次に、アプリを変更して、位置データをAPIに送信し、応答を取得して、結果をページに表示するようにします。

AngularでHTTPリクエストを行うには、 `+ HttpClientModule `をインポートする必要があります。 ` src / app / app.module.ts +`を開き、次の強調表示された行を追加します。

src / app / app.module.ts

...
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
   ...
   imports: [
       BrowserModule,
       RouterModule.forRoot(allAppRoutes),
       ReactiveFormsModule

   ]
   ...
})
...

次に、APIXU APIへのHTTP呼び出しを行うコードを記述する必要があります。 Angular _service_を作成してHTTPリクエストを作成することをお勧めします。 懸念事項の分離は、作成するアプリで重要です。 サービスを使用すると、アプリが作成するすべてのHTTPリクエストを1つのファイルに移動し、作成した任意の `+ .component.ts `ファイル内で呼び出すことができます。 特定の ` .component.ts +`ファイルにこれらのHTTPリクエストを「合法的に」書き込むことができますが、これはベストプラクティスではありません。 たとえば、リクエストの一部が複雑であり、データの受信後に後処理アクションを実行する必要がある場合があります。 アプリ内のいくつかの異なるコンポーネントがHTTPリクエストの一部を使用する可能性があり、同じメソッドを何度も記述したくない場合があります。

新しいターミナルウィンドウから、または現在のターミナルセッションでサーバーを停止して、次のコマンドを実行し、 `+ apixu +`というサービスを作成します。

ng g service apixu

次のような出力が表示されます。

Outputcreate src/app/apixu.service.spec.ts (328 bytes)
create src/app/apixu.service.ts (134 bytes)
...

このコマンドは、サービスファイル( + apixu.service.ts +)とテストファイル( + apixu.service.spec.ts +)を作成しました。

ここで、このサービスをプロバイダーとして `+ app.module.ts `ファイルに追加する必要があります。 これにより、アプリ内で使用できるようになります。 このファイルを開き、最初に ` ApixuService +`をインポートします。

src / app / app.module.ts

...
import { HttpClientModule } "@angular/common/http";

...

次に、新しくインポートされた `+ ApixuService `をプロバイダーとして ` providers +`ブロックに追加します。

src / app / app.module.tsファイル

...
@NgModule({
   ...
   providers: [],
   ...
})
...

Angularでは、作成したサービスを使用する場合、 `+ module.ts `ファイル内でそのサービスをプロバイダーとして指定する必要があります。 この場合、 ` app.module.ts +`でアプリケーション全体のプロバイダーとして指定しました。

最後に、 `+ src / app / apixu.service.ts `ファイルを開きます。 サービスを作成するために必要なものの定型コードが表示されます。まず、Angularからの ` Injectable `インターフェースのインポート。次に、サービスが「 providedIn 」ルートインジェクターを使用する必要があるという事実(アプリケーション全体)。そして、サービスの_decorating_(これは事実上指定することを意味します)を ` @ Injectable +`として。

src / app / apixu.service.ts

import { Injectable } from '@angular/core';

@Injectable({
 providedIn: 'root'
})
export class ApixuService {

 constructor() { }
}

サービスを「+ @ Injectable 」として修飾すると、コンポーネント内で使用できるように、「 weather.component.ts +」のコンストラクタ内にこのサービスを注入できます。

アプリケーションを停止した場合は、次を実行して再起動します。

ng serve --o

前述のように、サービスはAPIXU APIにHTTPリクエストを作成し、 `+ app.module.ts `ファイルに ` HttpClientModule `をインポートして、アプリケーション全体でHTTPリクエストを作成する必要があります。 さらに、 ` apixu.service.ts `ファイル自体からAPIXU APIへのHTTPリクエストを行うために、 ` HttpClient `ライブラリを ` apixu.service.ts `ファイルにインポートする必要があります。 ` apixu.service.ts +`ファイルを開き、次の強調表示されたコンテンツを追加します。

src / app / apixu.service.ts

...

...

ここで、1つのパラメーターlocationをとるメソッド `+ getWeather()+`を記述する必要があります。 このメソッドは、APIXUにAPIリクエストを行い、取得した位置データを返します。

これには、APIXU APIにサインアップしたときに提供されたAPIキーが必要です。 https://www.apixu.com [APIXU]にログインすると、ダッシュボードが表示されます:

image:https://assets.digitalocean.com/articles/angular_bootstrap/step8.png [APIXU Dashboard]

キーが表示され、その下に、* Current Weather Forecast Weather *の両方のキーが事前に入力されたAPI URLへのリンクが表示されます。 *現在の天気*の詳細のHTTPSリンクをコピーすると、次のようになります。

+ https://api.apixu.com/v1/current.json?key =&q = Paris +

このURLは、パリの現在の天気の詳細を提供します。 代わりに、フォームの `+ location `を `&q = `パラメータに渡すことができるようにしたいと考えています。 したがって、URLから「 Paris 」を削除して、「 apixu.service.ts +」ファイルに追加します。

src / app / apixu.service.ts

...
export class ApixuService {

 constructor() {}





 }
}

これで、コンストラクタに `+ HttpClient `をインポートして注入し、使用できるようになりました。 また、 ` location `パラメータを取り、指定されたURLに対して ` GET `リクエストを行うメソッド ` getWeather()`を作成しました。 メソッドの ` location `パラメータからこの場所を直接提供するため、 `&q = +`パラメータは空白のままにしました。 最後に、メソッドを呼び出した人にデータを返しました。

これでサービスが完了しました。 サービスを `+ WeatherComponent `にインポートし、コンストラクターに挿入して使用し、 ` sendToAPIXU()`メソッドを更新して、新しく作成したサービスに場所を送信する必要があります。 ` weather.component.ts +`ファイルを開き、強調表示されたコンテンツを追加してこれらのタスクを完了します。

src / app / weather.component.ts

...
import { FormBuilder, FormGroup } from "@angular/forms";

...
constructor(
   private formBuilder: FormBuilder,

 ) {}
...
ngOnInit(){...}
sendToAPIXU(formValues){



}

`+ sendToAPIXU()`メソッドの以前の ` console.log `ステートメントを削除し、このコンテンツで更新しました。 これで、フォームの場所を以前に作成した ` sendToAPIXU()`メソッドに渡します。 その後、そのデータを ` ApixuService `の ` getWeather()`メソッドに渡し、その後その場所でAPIにHTTPリクエストを送信しました。 次に、返された応答をサブスクライブし、この例では、そのデータをコンソールに記録しました。 HTTPリクエストでサブスクライブメソッドを呼び出す必要があるのは、返される ` Observable +`レスポンスを読み取る方法ができるまでリクエストが開始されないためです。 _Observables_は、パブリッシャーとサブスクライバー間でメッセージを送信する方法であり、あらゆる種類のデータをやり取りできます。 サブスクライバーがサブスクライブするまで、オブザーバブルからデータを受信することはできません。その時点まで実行されないためです。

ブラウザでコンソールをもう一度開きます。 ここで、* London、UK と入力し、 Search for Weather *をクリックします。 タブの矢印をクリックすると、コンソールに天気の詳細のリストが表示されます。

image:https://assets.digitalocean.com/articles/angular_bootstrap/step8b.png [英国ロンドンの現在の天気を検索することによるコンソール出力]

出力には、必要なすべての天気情報を含むJSONオブジェクトが表示されます。 2つのオブジェクトが返されます: + current`オブジェクトと + location`オブジェクト。 前者は希望する天気の詳細を提供し、後者はあなたの場所に関する詳細を提供します。

これで、天気データがコンソールに正常に表示されました。 このチュートリアルを完了するには、これらの天気の詳細をHTMLで表示します。

ステップ9-アプリで天気データを表示する

コンソールに結果を表示することは、すべてが機能していることを確認するための良い最初のステップです。 ただし、最終的にはユーザーの天気データをHTMLで表示する必要があります。 これを行うには、返された天気データを保持する変数を作成し、HTMLで_interpolation_を使用して表示します。

補間により、ビューにデータを表示できます。 これを行うには、 `+ {{}} +`スタイルでプロパティをバインドし、HTMLでそのプロパティを表示する必要があります。

`+ weather.component.ts `ファイルを開き、APIから取得したJSONデータを割り当てる ` weatherData `という変数を作成します。 さらに、以前に ` .subscribe()+`ブラケットにあったコードを削除し、次の強調表示されたコードに置き換えます:

src / app / weather / weather.component.ts

...
export class WeatherComponent implements OnInit {
public weatherSearchForm: FormGroup;

...
sendToAPIXU(formValues){
   this.apixuService
   .getWeather(formValues.location)
   .subscribe(data =>

   }
}

変数「+ weatherData 」を作成し、「 any 」タイプのデータを保持できることを宣言しました。 次に、API呼び出しから受け取るデータをその変数に割り当てました。 最後に、取得した情報がすべて「 weatherData 」に保持されていることを再確認するために、「 console.log()+」ステートメントを追加しました。

この段階で、 `+ weather.component.ts +`ファイルは次のようになります。

src / app / weather / weather.component.ts

import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { ApixuService } from "../apixu.service";

@Component({
 selector: "app-weather",
 templateUrl: "./weather.component.html",
 styleUrls: ["./weather.component.css"]
})
export class WeatherComponent implements OnInit {
 public weatherSearchForm: FormGroup;
 public weatherData: any;

 constructor(
   private formBuilder: FormBuilder,
   private apixuService: ApixuService
 ) {}

 ngOnInit() {
   this.weatherSearchForm = this.formBuilder.group({
     location: [""]
   });
 }

 sendToAPIXU(formValues) {
   this.apixuService.getWeather(formValues.location).subscribe(data => {
     this.weatherData = data;
     console.log(this.weatherData);
   });
 }
}

戻って_London、UK_を再度検索すると、通常どおりオブジェクトがコンソールに出力されます。 ここで、このデータをHTMLで表示します。 コンソールで取得した気象データから「+ current 」オブジェクトを調べると、「 condition 」、「 feelslike_c 」、「 feelslike_f 」、「 temp_c 」、「 temp_f +」などの値が表示されます。といったように、これら5つのプロパティすべてを使用します。

`+ weather.component.html`ファイルを再度開き、表示したいデータに字幕を追加します。 これらの `+ <p> `タグを2番目の ` col-md-6 +`内に追加します。

src / app / weather / weather.component.html

...
<div class="col-md-6">
 <h3 class="text-center my-4">Weather Details:</h3>






</div>

次に、JSONオブジェクトから受け取ったデータをHTMLに追加します。

weather.component.html

...
<h3 class="text-center my-4 ">Weather Details:</h3>
<p class="text-center">
 Current weather conditions:
</p>
<p class="text-center">
 Temperature in Degrees Celsius:
</p>
<p class="text-center">
 Temperature in Degrees Farenheit:
</p>
<p class="text-center">
 Feels like in Degrees Celsius:
</p>
<p class="text-center">
 Feels like in Degrees Farenheit:

</p>
<p class="text-center">
 Location Searched:

</p>

HTML内の `+ weatherData `変数からデータを取得するときに、演算子 `?+`を使用しました。 この演算子は、_Elvis Operator_と呼ばれます。

HTTP呼び出しを行っているため、_asynchronous_リクエストを行っています。 ある時点でそのデータを取得できますが、すぐに応答するわけではありません。 ただし、Angularは、 `+ weatherData `変数から指定したデータを引き続きHTMLに入力します。 Angularが段落にデータを入力し始めるまでにデータを受信して​​いない場合、Angularがそのデータを見つけられないというエラーが表示されます。 たとえば、「。current 」または「 .location +」は未定義として表示されます。

エルビス演算子は_安全なナビゲーター_であり、これが起こるのを防ぎます。 それは、Angularに、先に進んでそのデータをHTMLで表示する前に、 `+ weatherData `が最初に定義されているかどうかを待機して確認するように指示します。 ` weatherData +`がすべての情報を取得すると、Angularはバインディングを更新し、データを通常どおり表示します。

最終的な `+ weather.component.ts +`ファイルは次のようになります。

weather.component.html

<div class="container">
 <div class="row">
   <div class="col-md-6">
     <h3 class="text-center my-4">Search for Weather:</h3>
     <form
       [formGroup]="weatherSearchForm"
       (ngSubmit)="sendToAPIXU(weatherSearchForm.value)"
     >
       <div class="form-group">
         <input
           class="form-control"
           type="text"
           id="weatherLocation"
           aria-describedby="weatherLocation"
           placeholder="Please input a Location"
           formControlName="location"
         />
       </div>
       <div class="text-center">
         <button type="submit" class="btn btn-success btn-md">
           Search for the weather
         </button>
       </div>
     </form>
   </div>
   <div class="col-md-6">
     <h3 class="text-center my-4">Weather Details:</h3>
     <p class="text-center">
       Current weather conditions: {{ this.weatherData?.current.condition.text
       }}.
     </p>
     <p class="text-center">
       Temperature in Degrees Celsius: {{ this.weatherData?.current.temp_c }}
     </p>
     <p class="text-center">
       Temperature in Degrees Farenheit: {{ this.weatherData?.current.temp_f }}
     </p>
     <p class="text-center">
       Feels like in Degrees Celsius: {{ this.weatherData?.current.feelslike_c
       }}
     </p>
     <p class="text-center">
       Feels like in Degrees Farenheit: {{
       this.weatherData?.current.feelslike_f }}
     </p>
     <p class="text-center">
       Location Searched: {{ this.weatherData?.location.name }}, {{
       this.weatherData?.location.country }}.
     </p>
   </div>
 </div>
</div>

目的のデータを出力するために、返されたJSON天気オブジェクトのパターンに従いました。 ファイルを保存し、ブラウザーに戻って「* London、UK *」と入力すると、右側に天気データが表示されます。

image:https://assets.digitalocean.com/articles/angular_bootstrap/step9.png [英国ロンドンの天気データを表示する完成したアプリ]

米国サンフランシスコ、*ダカール、セネガル、*ハワイ州ホノルル*など、さまざまな場所で試してください。 これらすべての場所について、それぞれの気象データが表示されます。

結論

Angular、Bootstrap、およびAPIXU APIを使用して天気アプリを作成しました。 Angularのベストプラクティスに従って、アプリケーションが適切に設計および適切にセットアップされていることを確認しながら、Angularプロジェクトをゼロからセットアップしました。

Angularは、小さなWebアプリケーションから大規模で複雑なアプリケーションまで、あらゆるものを簡単に作成できる高度なフレームワークです。 Angularは、他のフレームワークと同様に学習曲線を持っていますが、このような小さなプロジェクトは、すぐに学習し、生産的に使用するのに役立ちます。

アプリケーションへの追加を検討するもう1つの機能は、HTTP要求からのhttps://angular.io/guide/http#error-handling[handling errors]です。たとえば、無効な場所に入力する場合。 別の機能強化は、温度が特定のしきい値の間にある場合に異なる画像を表示することです。 他のAPIを使用して、Angularでさまざまなアプリケーションを作成することもできます。

また、https://ng-bootstrap.github.io/#/home [NgBootstrap]を使用することもできます。これは、Angular用に構築された特別なタイプのBootstrapです。 これにより、すべての標準Bootstrap JavaScriptウィジェットと、Angularに特に適合した標準インストールに含まれていない特別なウィジェットを使用できます。

このチュートリアルの完全なコードは、https://github.com/do-community/AngularAPIXUTutorial [GitHub]で入手できます。