[Aurelia] 未来志向JavaScriptフレームワーク Aurelia 入門 4 httpクライアントを使ってflickr APIを叩くの続きです。
Custom Elementを使っていきます。
概要
- Aureliaがcustom elementをloadする為にrequire elementを使用。
- 対応するview-modelとviewを作成。
Custom Elementの使い方
これまでのapp.html
old
<template>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">
<i class="fa fa-home"></i>
<span>${router.title}</span>
</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
<a href.bind="row.href">${row.title}</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="loader" if.bind="router.isNavigating">
<i class="fa fa-spinner fa-spin fa-2x"></i>
</li>
</ul>
</div>
</nav>
<div class="page-host">
<router-view></router-view>
</div>
</template>
このnav-barを別ファイルに置きます。
src/app.html
<template>
<require from='./nav-bar'></require>
<nav-bar router.bind="router"></nav-bar>
<div class="page-host">
<router-view></router-view>
</div>
</template>
これで ./nav-barからnav-bar要素を呼び出します。
そして、view-model: nav-bar.js, view: nav-bar.htmlを作ります。
src/nav-bar-.js
import {bindable} from 'aurelia-framework';
export class NavBar {
@bindable router = null;
}
Custom Elementを作るために、ClassをExportします。
ElementがHTMLで使えるようになると、ClassのどのpropertyがElementのAttributeとして現れるかフレームワークに伝える必要があります。
そのためにbindable decoratorを利用します。bindableはinjectと同様、AureliaにClassの情報を伝える一つの方法です。
src/nav-bar.html
<template>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">
<i class="fa fa-home"></i>
<span>${router.title}</span>
</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
<a href.bind="row.href">${row.title}</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="loader" if.bind="router.isNavigating">
<i class="fa fa-spinner fa-spin fa-2x"></i>
</li>
</ul>
</div>
</nav>
</template>
補足
- この方法でviewにrequireされたものはローカル扱いになるため、名前のconflictの心配はあまりない。
- Internal Renderingの為に、App ClassのRouterインスタンスと、NavBar elementの対応するpropertyを通じさせます。
- Custom Elementの名前は、@customElement('name')を使って決めれます。
- Custom Elementがviewを持たない場合は、@noView()を追記するとよい
- Shadow Domを使いたい場合は、@useShadowDOM()を追記するとよい