複数のプロジェクトをまとめて管理できるワークスペース
Angular 5までは、プロジェクトには1つのアプリだけが含まれていました。Angular 6では、複数のプロジェクトやライブラリーをまとめて管理する「ワークスペース」が利用できます。これに伴い、従来のプロジェクト設定ファイル(.angular-cli.json)は、ワークスペース設定ファイル(angular.json)に置き換えられました。
Angular 6のAngular CLIで「ng new」コマンドを実行すると、アプリのプロジェクトを1つだけ含んだワークスペースを生成します。ワークスペースにアプリのプロジェクトを追加するには、「ng generate application <アプリ名>」コマンドを実行します。
また、ワークスペースには、ほかのアプリから参照できるライブラリーのプロジェクトを含めることができます。ワークスペースにライブラリーのプロジェクトを追加するには、「ng generate library <ライブラリー名>」コマンドを実行します。
2つのアプリと1つのライブラリーを含んだサンプルコード(P002-workspace)で、ワークスペースの利用方法を説明します。このワークスペースでは、「ng new」コマンドで生成した1つ目のアプリ(P002-workspace)に、「ng generate」コマンドで2つ目のアプリ(SecondApp)とライブラリー(SharedLib)を追加しています。追加したアプリやライブラリーは、ワークスペースのprojectsサブフォルダーに配置されます(図5)。
angular.jsonにはリスト3のように、複数のプロジェクト設定が含まれており、defaultProject属性でデフォルトプロジェクトが設定されています。
{
(略)
"projects": {
"P002-workspace": {
(1つ目のプロジェクトの設定)
},
"P002-workspace-e2e": {
(1つ目のプロジェクトのe2eテスト設定)
},
"SecondApp": {
(2つ目のプロジェクトの設定)
},
"SecondApp-e2e": {
(2つ目のプロジェクトのe2eテスト設定)
},
"SharedLib": {
(ライブラリープロジェクトの設定)
}
},
"defaultProject": "P002-workspace" // デフォルトプロジェクト
}
「ng serve --aot」コマンドを実行すると、リスト3のdefaultProjectに指定されたP002-workspaceプロジェクトのアプリが実行されて、図6のように表示されます。
defaultProject以外のアプリを実行するには、アプリ名を指定して「ng serve SecondApp --aot」とします。実行すると、図7のように表示されます。
ライブラリーSharedLibはどちらのアプリからも参照できます。このサンプルでは、ライブラリーに含まれるサービスから「これはライブラリープロジェクトから~」という文字列を取得して画面表示します。詳細はサンプルコードを参照してください。
AngularコンポーネントをWeb標準の独自タグにするAngular Elements
Angular Elementsは、Angularのコンポーネントを、Web Componentsの「Custom Elements」として利用できる仕組みです。Custom Elementsは、独自のHTMLタグを定義できるWeb標準の機能です。
Angular Elementsの利用方法を、図8のサンプルで説明します。テキストボックスに文字列を入力してボタンを押すと、Custom ElementsのHTML要素が動的にページに追加され、対応するAngularのコンポーネントが表示されます。このときテキストボックスの入力値が、HTML要素のtitle属性を介してAngularコンポーネントに渡されます。
Angular Elementsを利用するには、まず前述した「ng add @angular/elements」コマンドで、AngularアプリにAngular Elementsの機能を追加します。次に、モジュール定義ファイルapp.module.tsで、Custom ElementsにするAngularコンポーネント(ElemComponent)を、entryComponents属性に指定します。これは、Custom Elementsとして読み込まれる前にElemComponentを準備しておくためです。
@NgModule({
(略)
entryComponents: [ElemComponent]
})
コンポーネント定義ファイルapp.component.tsのコンストラクターで、ElemComponentをCustom Elementsとして登録します。
// コンストラクターでInjectorを依存性注入で受け取る ...(1)
constructor(private injector: Injector) {
// AngularコンポーネントからCustom Elementを生成 ...(2)
const elem = createCustomElement(
ElemComponent, { injector: this.injector });
// Custom Elementにcustom-elementという名前を付けて登録 ...(3)
customElements.define('custom-element', elem);
}
(2)のcreateCustomElementメソッドで、AngularコンポーネントからCustom Elementsを生成します。引数として必要となるinjectorは、コンストラクターの依存性注入で受け取ります(1)。次に、生成したCustom Elementsを(3)のcustomElements.defineメソッドに指定して、「custom-element」というHTML要素名を付けます。以後、HTML内の<custom-element>要素は、AngularのElemComponentになります。
画面のボタンをクリックしたときの処理はリスト6です。title属性を指定した<custom-element>要素を、動的にHTMLへ追加します。リスト5(3)で<custom-element>要素にElemComponentを登録しているので、<custom-element>要素を追加した場所にElemComponentが表示されます。このとき、title属性の値がElemComponentに渡されます。
addElemComponent() {
// <custom-element title='(タイトル)'></custom-element>要素を追加
const elem = document.createElement('custom-element');
elem.setAttribute('title', this.title);
document.getElementById('elements').appendChild(elem);
}
ElemComponentは、リスト7のような単純なコンポーネントです。(1)の記述により、HTML要素のtitle属性に指定された値がコンポーネントのtitle変数に代入されます。title変数の値は、コンポーネントの表示に反映されるようになっています。
export class ElemComponent {
// タグのtitle属性から値を取得 ...(1)
@Input() title:string = '';
}
現状のAngular Elementsは、Angularアプリの中で、AngularコンポーネントをCustom Elementsとして利用することを主眼にしており、Angular以外の環境での利用は現在開発中です。実現すれば、一般的なWebページや、ReactのようなAnguar以外のフレームワーク上で、AngularコンポーネントをCustom Elementsとして利用できるようになる見込みです。
