複数のプロジェクトをまとめて管理できるワークスペース
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として利用できるようになる見込みです。