Lightning Component のページ遷移の問題点
Lightning Component は「 Single-Page-Application (SPA) を構築できるフレームワークだ!」なんて触れ込みもありましたが、実のところ1ページ内でViewを切り替えるための Router をライブラリに持っていません。
また、ページ内でのView切替するための仕組みもなく、以前紹介し唯一の可能性であった navigateToComponent() もお蔵入りになってしまっています。
つまり、Lightning Component のページ遷移を考えたときによい解決策がない状態でした。
LightningRouter の提案
実は、Winter'16 で aura:locationChange イベントが追加されました。このイベントは、URLのクエリー文字列やハッシュが変更されたタイミングで発火するものです。この機能追加によって、待望の Router 機能を実装できるようになりましたので、Lightning Component を実現する LightningRouter コンポーネントをサンプル実装してみました。
サンプル実装
ルーティングを処理するコンポーネントのサンプル実装です。
初期表示するコンポーネント、ルーティング情報を属性として与えられることで、動作するようになっています。ルーティング処理自体は、locationが変化した際に発生するイベントを受け取り、ルーティング情報に従って{v.body}に表示するコンポーネントを切り替えているだけで単純なものです。
<aura:component>
<aura:handler event="aura:locationChange" action="{!c.render}" />
<aura:handler event="init" action="{!c.render}" />
<aura:attribute name="init" type="String" access="global" />
<aura:attribute name="route" type="String" access="global" />
{!v.body}
</aura:component>
({
render : function (component, event, helper) {
var token = event.getParam("token");
var querystring = event.getParam("querystring");
var route = JSON.parse(component.get("v.route"));
if($A.util.isUndefined(token)) {
token = component.get("v.init");
}
var cmpName = route[token];
$A.createComponent(
"c:" + cmpName,
{
"aura:Id": cmpName,
},
function(newCmp){
if (component.isValid()) {
var body = component.get("v.body");
body.pop();
body.push(newCmp);
component.set("v.body", body);
}
}
);
}
})
利用方法
下記のように呼び出します。init 属性には初期表示する Lightning Component、route 属性には、ハッシュとそのハッシュがセットされた場合に表示する Lightning Component をJSON(連想配列)で記述します。
<aura:application>
<c:LightningRouter
init="Sample1"
route='{
"Sample1" : "Sample1Cmp",
"Sample2" : "Sample2Cmp"
}'
/>
</aura:application>
あとは、ページとして表示する Lightning Component を用意し、下記のようにアンカータグでハッシュを呼び出せば、表示する Lightning Component を切り替えてページ遷移します。
<aura:component>
<div>
Hello, Sample1!
<a href="#Sample2">Sample2</a>
</div>
</aura:component>
<aura:component>
<div>
Hello, Sample2!
<a href="#Sample1">Sample1</a>
</div>
</aura:component>
GitHubリポジトリ
サンプルソースコードについては、ここで公開しています。
https://github.com/kuratani/LightningRouter
おわりに
以上のように、 Winter'16 で追加になったイベントを用いて、これまで Lightning Component になかった Router機能を実装しました。今回実装したものは、単純に Lightning Component を切り替えるシンプルな実装となっています。
実際に製品開発などで利用する場合は、~~Salesforce1で動作するように修正する、~~ページ遷移時のアニメーションを追加する、など必要に応じて拡張していく必要があります。