Using Angular Elements – Why and How? – Part 1

Getting Started

まず、システム内に新しいAngularプロジェクトを作成することから始めます。 このために、最新バージョンのAngular CLIがインストールされていることを確認してください。 ターミナルで次のコマンドを実行します。

$ npm install -g @angular/cli

このインストールが完了したら、これを使用して、次のようにシステム内に新しい初期アプリケーションを作成できます。

この CLI は、必要な Angular パッケージと依存関係を angular-app という名前のフォルダーにインストールします。 次のコマンドを実行することにより、このアプリケーションをブラウザに提供できます:

$ cd angular-app
$ ng serve --open
// --open flag will open the browser for you

ご覧のとおり、アプリには画面に表示できるものがすでにいくつか入っています。 しかし、それらは必要ではありません。 そこで、コードエディター(私は❤️VS Code)に戻り、src/app/app.component.htmlファイル内のすべてを削除し、単一の<h1>要素を記述します。

<h1>Welcome To Angular Elements!</h1>

ファイル構造を見てみると、angularの各コンポーネントは多数のファイルで構成されていることがわかります。 Appコンポーネントだけでも、.ts.html.css、そしてテストを含むspec.tsファイル、module.tsファイルが存在します。 また、CLI を使用してアプリケーションを作成する際にルーティング機能を追加することを選択していた場合、オプションの routing.module.ts ファイルがあります。

コンポーネントのためにこれらのファイルすべてを記述する代わりに、Angular CLI ではこれらのファイルを生成する省略記法を提供しています。

$ ng g c HelloWorld

このコマンドは、app フォルダーの中に hello-world という名前のフォルダーを作成します。 このファイルを開くと、その中に次の 4 つのファイルがあります:

  • hello-world.component.css
  • hello-world.component.html
  • hello-world.component.spec.ts
  • hello-world.component.ts

今回は.html.tsだけを使用することにしましょう。 ng g c コマンドに渡すことができる追加のフラグがあります。 しかし、物事をシンプルかつ要領よく進めるために、私はそれらを使用しません。 このコマンドの使用方法については、Angular Docsを確認してください。

hello-world.component.tsファイルの内部では、selectorapp-hello-worldに設定されていることがわかります。 そこで、これをapp.component.htmlに次のように追加します:

<h1>Welcome To Angular Elements</h1>
<app-hello-world></app-hello-world>

すると、hello-world.component.htmlの内容がブラウザに表示されます。

これで初期設定は完了しました。

Convert A Component Into Custom Element

今、私たちは、単に画面にテキストを表示するシンプルな HelloWorld コンポーネントを使用しています。 このコンポーネントをより動的な方法でアプリに挿入する方法を見てみましょう。 これを行うには、app-hello-worlddivbuttonに置き換えてみましょう。 また、buttonclickリスナーを追加して、誰かがボタンをクリックしたときにHelloWorldコンポーネントを表示できるようにします。 これはshowMessage()関数で処理されます。

<h1>Welcome To Angular Elements</h1>
<div></div>
<button (click)="showMessage()">Display?</button>

次に、showMessage() 関数を app.component.ts ファイルで定義する必要があります。 ここでは、通常の DOM 操作を使用して、divhelloid を使用して選択することで取得します。 次に、innerHTML 関数を適用して、次のように app-hello-world コンポーネントを挿入します:

export class AppComponent {
showMessage() {
const hello = document.getElementById('hello');
hello.innerHTML = '<app-hello-world></app-hello-world>';
}
}

ブラウザでボタンをクリックすることもできますが、何も起こらないことを今ここでお伝えしておきます。 しかし、ブラウザの開発ツールに移動してそこを見ると、HelloWorldコンポーネントが挿入されていることがわかります。

画面上でコンポーネントが見えない理由は、app-hello-worldタグがテンプレートに動的に挿入されたため、Angularが認識できないからです。 Angular は、すべての要素がテンプレート内に存在する必要があり、または、動的コンポーネント ファクトリを使用して、コードを通じて実行時にコンポーネントをインスタンス化する必要があります。 Angular 要素を使用することにより、動的にタグを挿入するだけで、Angular 自体が私たちのためにコンポーネントをインスタンス化します。 それではいよいよ、このコンポーネントをアプリでどのように使用するかを見ていきましょう。 まず、ng add コマンドを使用して Angular Elements をアプリにインストールします。

$ ng add @angular/elements

これをインストールしたら、app.module.ts に移動して @NgModule に以下の変更を加えてください。

import {NgModule, Injector} from '@angular/core';
import {createCustomeElement} from '@angular/elements';
@NgModule({
declarations: ,
imports: ,
entryComponents: ,
providers: ,
bootstrap:
})

次に、AppModule クラスで、constructor 関数を記述し、createCustomElement の新しいインスタンスを作成して、次のように HelloWorldComponent を渡します:

export class AppModule {
constructor(injector: Injector) {
const custom = createCustomElement(HelloWorldComponent, {injector: injector});
}
}

コンポーネントと一緒に、injector も渡す必要があります。 injector は依存関係を解決するために使用されるものです。 これで、カスタム要素としてHelloWorldComponentのインスタンスが作成されました。 次に、customElements API を使用して、コンポーネントのタグを app-hello-world として定義します。

customElements.define('app-hello-world', custom);

hello-world.component.ts ファイルに戻って、@Component セクション内の selector を削除またはコメントします。

ng serve --open コマンドを再実行して、Angular が私たちが行ったすべての変更を取り込むことを確認します。 これは、Angular が「HTMLElement の構築に失敗した」ことが原因である可能性があります。 この問題を解決するには、webcomponentjsポリフィルをインストールします:

$ yarn add @webcomponents/webcomponentsjs

次に、polyfills.tsファイルに移動し、以下をインポートします:

import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js';

最後に!HelloWorldComponentを表示するために、webcomponentjsポリフィルをインストールします:

$ yarn add @webcomponents/webcomponentsjs

最後に、polyfills.tsファイルを移動し、以下をインポートします。

このボタンをクリックすると、カスタム要素が画面に表示されるようになります。