各ユニットのJavascriptファイルは、ブラウザにロードされる必要があります。ロード方法にはオートロードとマニュアルロードがあります。オートロードはユニットのタグの属性にbm-autoload属性を指定することで、自動的に必要なファイルをロードし、タグをインスタンス化します。マニュアルロードはscriptタグに明示的に必要なファイルを記述し、ユニットをロードします。前者は手軽なのですが、ロードするファイルがユニットごとにデフォルトでは3つ必要になります。後者の場合は、例えばWebpackなどを使うと、複数のユニットを一つにまとめることができます。
ここでは、ユニットのロード方法について説明します。
ここでは、ユニットのクラスファイルのロードについて説明します。設定、HTMLやCSSのロードについては以下をご覧ください。
ユニットのロード方法には、以下の方法があります。
ユニットのタグにbm-autoload属性を付加することで、ユニットに必要なファイルが自動的にロードされます。その際、ファイルへのURLを記述する方法と、デフォルトのパスやファイル名を使う方法があります。
これは"サンプルユニットを作る"で使用した方法です。カスタムタグの“bm-autoload”属性にJavascriptファイルへのURLを記述します。
<pad-hello bm-autoload="/pad-hello.js"></pad-hello>
するとBitsmistJSライブラリが、指定されたURLからファイルを自動的にダウンロードします。その後ユニットが初期化され、HTML/CSSファイルがロードされて画面に表示されます。
この例では相対パスを使っていますが、絶対パスでも構いません。ただし、XMLHttpRequestを使用して取得しているため、絶対パスを使って別のオリジンからロードする場合は、サーバ側でAccess-Control-Allow-Originヘッダーを付加する必要があります。
bm-autoload属性の値にURLを指定しない場合は、デフォルトのパスとファイル名が使用されます。
<pad-hello bm-autoload></pad-hello>
と指定された場合、デフォルトのパスは現在のパス(現在表示しているhtmlのパス)、デフォルトのファイル名はタグ名に拡張子をつけた“pad-hello.js”となります。例えばhttps://example.com/index.htmlを表示している場合、https://example.com/pad-hello.jsが読み込まれます。
デフォルトのパスとファイルは設定で変更することが可能です。
通常のJavascriptのようにHTMLファイル内に<script>タグを記述してインポートします。
<script type='text/javascript' src='/bar-hello.js'></script>
上記の文でユニットは読み込まれているため、カスタムタグではbm-autoload属性は不要です。
<pad-hello></pad-hello>
ただし、この方法でも、HTML/CSSファイルは必要な時に呼ばれるオートロード形式になります。HTML/CSSファイルも一緒にマニュアルでロードしたい場合は、Webpackなどを使用して、ファイルをまとめる必要があります。その場合は、複数のユニットを一つのファイルにまとめることも可能です。
HTMLのみのユニットの場合、このロード方法は使用できません。
各ユニットの設定の“unit.units”セクションに、追加するユニットを記述することで、そのユニットの子ユニットとして追加することができます。オートロード、マニュアルロードのいずれも使うことができます。
{ "unit": { "units": { "PadSetting": { "unit": { "options": { "parentNode": "#widgets" } } } } } }
追加するユニットは、親ユニット配下の“parentNode”で指定されたノードに、追加されます。
“unit”セクションはUnitPerkによって、操作されます。設定の記述方法については以下を参照ください。
プログラムから動的にユニットを追加することも可能です。その場合、2つの方法があります。どちらの方法でもオートロード、マニュアルロードのいずれも使うことができます。
ドキュメントツリーにタグを追加します。既にロードされているユニットの場合、即座にインスタンス化されます。
this.insertAdjacentHTML("afterbegin", "<pad-filter></pad-filter>");
ロードが必要な場合、必要な情報をタグ属性に指定し、追加した後にunit.materializeAllスペルを実行してください。ユニットがロードされて、インスタンス化されます。
this.insertAdjacentHTML("afterbegin", "<pad-filter bm-autoload bm-path='common'></pad-filter>"); this.use("spell", "unit.materializeAll");
各ユニットが持っているunit.materializeスペルを使用して、そのユニットの子ユニットして追加することができます。materializeスペルに設定内容を記述したオブジェクトを渡すことで、初期化できます。
this.use("unit.materialize", "PadFilter", { "unit": { "options": { "path":"common", "parentNode":"#pads" } } });
上記の例の場合、ユニットの#padsノードに、PadFilterという子ユニットを追加しています。
materializeAll/materializeスペルはUnitPerkによって提供されます。
独自のイベントハンドラなどを持たない単純なユニットの場合、別のユニットをもとに新しいユニットを作成し、それを利用することができます。その際、表示するHTMLファイルを指定する方法と、デフォルトのファイルをロードする方法があります。
bm-autoload属性にHTMLファイルへのURLを指定した場合、内部で自動的にUnitクラスを継承した新しいクラスを作成し、そのクラスをタグと紐付けます。
<pad-hello bm-autoload="/pad-hello.html"></pad-hello>
上記の例の場合、Unitクラスを継承したPadHelloクラスが作成され、pad-helloタグに紐づけられます。その後タグがインスタンス化され、Unitクラスの初期化が始まり、HTMLファイルとCSSファイルがサーバから読み込まれ、カスタムタグ内に表示されます。
デフォルトのパスとファイル名を利用する場合、bm-automorph属性を指定します。
<pad-hello bm-automorph></pad-hello>
デフォルトではUnitクラスを継承しますが、bm-automorph属性でスーパークラスを指定することもできます。
<pad-hello bm-automorph='MyUnit'></pad-hello>
なお、指定するクラスをロードする必要がある場合、bm-autoload属性を使ってロードする必要があります。
<pad-hello bm-autoload='https://example.com/my-unit.js' bm-automorph='MyUnit'></pad-hello>
この場合、https://example.com/my-unit.jsがロードされた後に、MyUnitクラスを継承したPadHelloクラスが作成され、タグに紐づけられます。
最初に読み込まれたHTMLファイル(例えばindex.html)内にあるロード対象ユニットは、DOMContentLoadedイベントでロードが開始されます。ロード対象ユニットは“bm-autoload”、または“bm-automorph”属性を持つタグです。
また読み込まれたユニットのHTMLがノードにアタッチされた時に、そのユニット内にロード対象ユニットがあれば、さらにそれらのファイルがロードされます。
サンプルとして作成したユニットではファイルは全てルート直下に置きました。実際の運用では、ユニットを分類して特定のフォルダにまとめることになると思います。その場合、bm-autoload属性でURLを個別に指定するのではなく、デフォルトのパスをうまく使うことで、記述量を減らすことができます。ここではデフォルトのパスについて説明します。
デフォルトのパスは、以下の設定を元に決定されます。
システムユニットパスは、グローバル設定・各ユニット固有の設定の両方で行うことができます。システム設定、ユニット設定の両方に同じ指定がある場合は、各ユニットの設定が優先されます。これを利用して、特定のユニットだけシステム全体とは違うURLをベースとすることもできます。
上記の設定を繋げたフォルダからファイルがダウンロードされます。いずれも初期値は““(空文字列)です。例として以下のように設定したとします。
設定 | 値 |
---|---|
system.unit.options.path | https://example.com/units/ |
ヘッダーユニット”bar-header”が以下のようにHTMLファイルに指定してあった場合、
<bar-header bm-autoload bm-path="common"></bar-header>
ユニットはhttps://example.com/units/common/bar-header.jsから読み込まれます。
デフォルトパスの指定は設定、またはタグの属性で行います。設定には大きく分けると、全ユニットで共通のグローバル設定と、ユニット固有の設定があります。
設定の詳細については設定を参照ください。
システムユニットパスは、基本的にはグローバル設定で行います。
BITSMIST.v1.Unit.use("setting.merge", { "system": { "unit": { "options": { "path": "https://example.com/units/" } } }, });
上記の内容を、例えば“settings.js”という名前で保存し、HTMLのスクリプトタグで読み込みます。
<script type='text/javascript' src='/settings.js'></script>
ユニットパスはそれぞれのユニットの属性で設定します。
<bar-header bm-autoload bm-path="common"></bar-header>
“unit”セクションを使って追加、またはコードから動的に追加する場合は、セクション内のユニットの設定に記述することもできます。
{ "unit": { "units": { "PadSetting": { "unit": { "options": { "path": "common" } }, } } } }
this.cast("unit.materialize", "PadSetting", { "unit": { "options": { "path": "common" "parentNode": "#pads" } } });
_getSettings()や外部設定ファイルを使う方法では、デフォルトのパスの指定はできません。なぜならそれらの方法はユニットがロードされた後に実行されるためで、ロード前に指定することができないからです。
bm-autoload属性でURLを指定しない場合、デフォルトのファイル名が使用されます。デフォルトではタグ名がファイル名となりますが、設定で変更することが可能です。
ファイル名は、bm-filename属性または設定の“unit.options.fileName”で変更可能です。ここで指定したファイル名に拡張子“js”を付加したものが、ロードするファイル名となります。
ファイル名はそれぞれのタグの属性で指定します。拡張子は不要です。
<bar-header bm-autoload bm-filename="header"></bar-header>
“unit”セクションを使って追加、またはコードから動的に追加する場合は、セクション内のユニットの設定に記述することもできます。
{ "unit": { "units": { "BarHeader": { "unit": { "options": { "fileName": "header" } }, } } } }
document.querySelector("bm-router").use("unit.materialize", "BarHeader", { "unit": { "options": { "fileName": "header", } } });
bm-autoload属性にURLを指定した場合、その値に応じて“unit.options.path”, “unit.options.fileName”の設定が自動的にセットされます。またURLにHTMLを指定した場合は, さらに“unit.options.autoMorph”がTrueに設定されます。
例としてbm-autoloadにhttps://example.com/unit/transactions/pad-main.jsと指定された場合、各設定が以下のようにセットされます。
設定 | 値 |
---|---|
unit.options.path | https://example.com/unit/transactions/ |
unit.options.fileName | pad-main |