search
LoginSignup
4

More than 5 years have passed since last update.

posted at

Aurelia hack 02 ~Aureliaの構造~

前回 に引き続きひな形について、今回は構造を見ていきましょう。

何を書けばどう動くのか

まずソースコードの全体的な構造です。
実際にソースコードをのぞきながら読み進めてみてください。

aurelia-hack02-001.png

index.html -> main.js

index.html がブラウザに読み込まれると aurelia-bootstrapper によって aurelia-app 属性に従ってエントリポイントが呼び出されます。今回は aurelia-app="main" の記述に従って main.js が読み込まれます。

main.js -> app

続いて画面の外枠と、内側に表示する画面のルーティングを行う app モジュールが読み込まれます。

src/main.js
import 'bootstrap';

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging();

  //Uncomment the line below to enable animation.
  //aurelia.use.plugin('aurelia-animator-css');

  //Anyone wanting to use HTMLImports to load views, will need to install the following plugin.
  //aurelia.use.plugin('aurelia-html-import-template-loader')

  aurelia.start().then(a => a.setRoot());
}

この a.setRoot() が最初の画面を決定しますが、引数がなければ自動的に app が選択されるようになっています。
例えば welcome から起動したい場合は a => a.setRoot('welcome') と書きます。

各モジュールの記述はコンパイル済みファイルが展開される dist ディレクトリからの相対パスになっています。
例えば src/routes/sample.js (&.html) を指定する場合は routes/sample と書いてください。

app -> welcome

ルーティング

app.js を見てみると、App クラスに configureRouter() というメソッドが定義されています。
ViewModel に configureRouter() が定義されていると、Aurelia は「この画面ではルーティングをやりたいんだな?」と判断してくれます。

ひな形では最初のルートに対して welcome を設定していますので、app.html の <router-view></router-view> の部分に welcome が表示されるという流れになります。

View と ViewModel

Aurelia は MVVM (Model View ViewModel) という発想に基づいています。

app や welcome はそれぞれ View (.htmlファイル) と ViewModel (.js) ファイルに分かれています。

  • View welcome.html (表示内容のテンプレート)
src/welcome.html
<template>
  <section class="au-animate">
    <h2>${heading}</h2>
    ~省略~
  </section>
</template>
  • ViewModel welcome.js (表示するデータやユーザの操作に対応するアクション)
src/welcome.js
export class Welcome {
  heading = 'Welcome to the Aurelia Navigation App!';
  firstName = 'John';
  lastName = 'Doe';
  previousValue = this.fullName;
  // ~省略~
}

これらは基本的に同じ名前を付けることでペアとなります。ファイル名はそれぞれハイフン区切りのスネークケース snake-case.js, snake-case.html で、ViewModel のクラス名はパスカルケース export class PascalCase にします。
もちろん、別の名前を付けたり別の場所にある View を設定したりすることも可能です。

Aurelia は Angular2 によく似ていますが、この「特に注文がなければ名前だけで役割を決定する」という規約志向なところが Aurelia の特徴となっています。

これは各画面だけでなく、その中で使う部品についても同様です。

画面に表示する部品を作ってみよう

ひな形ではCSSフレームワークとして Twitter Bootstrap が使われています。Twitter Bootstrap は CMS なんかを作るときにとくに助かるのですが、構造的な意味の薄い(見た目のためだけの)コードによって HTML が冗長になりがちです。

dropdown custom element を作る

こちら の例を引用します。そのまま記述するとしたら以下のようになります。

dropdownメニュー部品だけでこのボリューム
<div class="dropdown">
  <button class="btn btn-default dropdown-toggle" type="button"
    data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
    サンプル
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu">
      <li><a href="#">Welcome</a></li>
      <li><a href="#users">Github Users</a></li>
      <li><a href="#child-router">Child Router</a></li>
  </ul>
</div>

これを部品 (custom element) として定義することで、以下のように使うことができます。

src/welcome.html
<template>
  <!--作った部品を読み込む-->
  <require from="dropdown"></require>
  <section class="au-animate">
    <h2>${heading}</h2>

    <!--作った部品を使う-->
    <dropdown label="サンプル">
      <li><a href="#">Welcome</a></li>
      <li><a href="#users">Github Users</a></li>
      <li><a href="#child-router">Child Router</a></li>
    </dropdown>
  </section>
</template>

aurelia-hack02-002.png

ボタン部分を表現するためのコードがごそっとなくなって、ドロップダウンメニューの内容に集中できるようになります。

  • View 新規作成: src/dropdown.html
src/dropdown.html
<template>
    <div class="dropdown">
        <button class="btn btn-default dropdown-toggle" type="button"
                data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
            ${label}
            <span class="caret"></span>
        </button>
        <ul class="dropdown-menu">
            <content></content>
        </ul>
    </div>
</template>
  • ViewModel 新規作成: src/dropdown.js
src/dropdown.js
import {bindable} from 'aurelia-framework'

export class Dropdown {

    @bindable label;

}

ドロップダウンボタンのタイトル部分に表示するラベルと、それからドロップダウンメニューの内容を外部から設定できるようになっています。
knockout.js Components などでは作った custom-element はフレームワークに登録する処理を書く必要がありますが、それらは Aurelia では必要ありません。

@bindable

ViewModel のプロパティに @bindable を付けることで、プロパティを外部から設定・バインドすることができるようになります。
つまり、<dropdown label="サンプル"> のように書けばOKです。
動的に変更するなら <dropdown label="${sampleLabel}"> でもいいですし、<dropdown label.bind="sampleLabel"> でもOKです。

<content></content>

custom element の中身を使うには、中身を配置したい場所に <content></content> を記述します。下記の「ここから~ここまで」の部分が上記 dropdown.html の <content></content> の部分に配置されます。

<dropdown label="サンプル">
  <!--ここから-->
  <li><a href="#">Welcome</a></li>
  <li><a href="#users">Github Users</a></li>
  <li><a href="#child-router">Child Router</a></li>
  <!--ここまで-->
</dropdown>

ViewModel を省略することもできるよ

今回の ViewModel は bindable なプロパティが一つあるだけです。ロジックがまったくいらないので、ViewModel を省略することもできます。

まずは dropdown.html の template エレメントに bindable="label" を追加します。ViewModel の @bindable label と同義です。

src/dropdown.html
<template bindable="label">
複数ある場合は bindable="label,foo,bar" のようにカンマ区切りで記述します。
~省略~
</template>

src/dropdown.js は消してしまって大丈夫です。その代わり custom element としてちゃんと見つけられるように、読み込み部分を from="dropdown" から from="dropdown.html" に変更します。

src/welcome.html
<template>
  <!--作った部品を読み込む-->
  <require from="dropdown.html"></require>
  ~省略~
</template>

部品をどこでも使えるようにするには

追加した部品を使うためには <require from="dropdown"></require> のようにモジュール参照を書く必要がありますが、以下の方法で <require> を書かなくても、いつでもどこでも custom element を使えるようにすることができます。

まず、いろんな場所で使いたい部品は1か所にまとめましょう。さらにまとめたフォルダに index.js を新規作成します。

src/
 └─ resources/   ...共通部品置き場
     ├─ dropdown.html
     ├─ ...
     └─ index.js

新規作成した index.js は以下のように記述します。

src/resources/index.js
export function configure(aurelia) {
    aurelia.globalResources('dropdown.html');    // ViewModel 省略したなら .html をつけよう
    // 部品が増えたら同じようにここに追加していく
}

最後に main.js に1行追加します。

src/main.js
import 'bootstrap';

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging()
    .feature('resources');    // feature として resources/index.js を登録する

  aurelia.start().then(a => a.setRoot());
}

これで <require from="dropdown.html"></require> は不要になり、管理が楽になりました。
今後のサンプルも resources ディレクトリを使っていきます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4