フロントエンドの業務でAJAXでバックエンドと接続して内容を取得してデータを表示する、なんていう場面は多々あると思います。
ただ、AJAXで取得したデータを一つ一つ要素を作成して流し込んでいく事が面倒だったり、表示の並びなどはViewだけでちょっと触るだけで変更できればバックエンドの処理が減って良かったりします。
今回は、jQueryとJavaScriptの便利ライブラリ集Lodashのテンプレート機能とソート機能を使ってみたいと思います。
デモ
codepenでデモを作ってみました。
See the Pen lodash Template Test by koka (@kokaben) on CodePen.
ミニブログを想定して、画像とタイトル、日付、タグ、内容をオブジェクトにしてそれを配列で持たせています。
HTML側にscriptタグでテンプレートを宣言して、ボタンを押下するとそのテンプレートと配列を基に記事を表示するといった流れになります。
Lodashについて
LodashはJavaScriptの配列やオブジェクトを超便利に扱えるライブラリです。
JavaScriptもES2015以降便利な関数が増えてきましたのでそちらもオススメなのですが、業務で使うとなればお客様の環境に合わせて書き分ける必要が出てきます。Lodashはブラウザ差異を吸収する役目も担うので、安全性を取るなら使わない手は無いでしょう。
LodashはライブラリをダウンロードしてHTMLソースに
<script src="lodash.js"></script>
と読み込むだけで機能します。
_←がLodashを表す文字となります。jQueryの$と考え方は同じです。
Lodashの関数を使用するには_.forEach(array,function(e){})のような書き方での使用も可能ですし、_(array).forEach(array,function(e){}).filter(...)のような、jQueryのようなメソッドチェーンで結果を繋いでいくような書き方も可能です。
テンプレートについて
テンプレートはHTMLとちょっとしたテンプレート構文を用いて書く事ができます。
html側
<script type="text/template" id="template-article">
<li>
<div class="article-wrap">
<div class="article-image">
<img src="<%= image %>" alt="">
</div>
<div class="article-inner">
<div class="article-inner-title">
<h3><%= title %></h3>
</div>
<div class="article-inner-info">
<i class="fa fa-calendar" aria-hidden="true"></i>
<span class="info-date"><%= date %></span>
<i class="fa fa-tag" aria-hidden="true"></i>
<span class="info-category"><%= category %></span>
</div>
<div class="article-inner-text">
<div class="text-inner"><%= text %></div>
</div>
</div>
</div>
</li>
</script>
テンプレート内で出てくる<%= hoge %>がテンプレート構文で、その値はJavaScriptでLodashのcompile関数で指定するオブジェクトのキー名を指定します。
JavaScript側
JavaScriptでは、まず変数を宣言してロード時に初期化しておきます。今回は説明しやすいようにグローバルで宣言しています。
// 変数宣言
var template,$template,compile,articleElem;
// ロード時のイベント
$(function(){
// 出力先の取得
articlesElem = $("#output")[0];
// Lodashのtemplateを使いやすいように変数に参照しとく
template = _.template;
// HTMLよりテンプレートの取得
$template = $("#template-article")[0];
// コンパイル機能を使いやすいよう部分適用しとく
compile = template($template.innerHTML);
});
Templateを展開するには、前述のcompile関数を使用します。
compile関数は読み取ったテンプレートを基に与えられた変数のキー名とテンプレートに記述されたテンプレート構文のキー名と合致すれば、値を代入してHTMLとして出力してくれます。
// テンプレートを使って記事を表示する
function showArticle(target,data){
var html = "";
_.forEach(data,function(elem){
html += compile({
title: elem.title,
date: elem.date,
text: elem.text,
category: elem.category,
image: elem.image,
});
});
target.innerHTML = html;
}
compile関数の前に_.forEach()というLodashのforEach関数を使用して配列をぐるぐる回して結果をhtml変数に足し込んでいき、最後はinnerHTMLに入れる事で結果が出力されます。
イベント
HTMLにボタンを設置しており、そのボタン各々のdata属性にソートの条件を持たせて、それに沿ってLodashのorderBy関数にて配列内のオブジェクトの並べ替えを行ってから出力させています。
// ボタン押下(1つのソート条件)
$(document).on("click",".btn",function(e){
e.preventDefault();
var sortDest = this.dataset.sort;
var sortType = this.dataset.type;
var sorted = _.orderBy(articles,[sortType],[sortDest]);
showArticle(articlesElem,sorted);
});
このorderByの引数はorderBy(並び替えたい配列,[ソートに使うキー名0,ソートに使うキー名1,...],[ソート順序0,ソート順序1,..])です。
ソート順序は"asc"(昇順)もしくは"desc"(降順)で指定します。
複数条件でソートする
前述のとおり、orderByはソート順序を指定できますが、複数条件でソートする事が可能です。第2引数と第3引数の型が配列をとっており、それぞれの配列のindexが対となっています。
// ボタン押下(2つのソート条件)
$(document).on("click",".btnAlt",function(e){
e.preventDefault();
var sortDest = this.dataset.sort;
var sortType = this.dataset.type;
var sortDestAlt = this.dataset.sortAlt;
var sortTypeAlt = this.dataset.typeAlt;
var sorted = _.orderBy(articles,[sortType,sortTypeAlt],[sortDest,sortDestAlt]);
showArticle(articlesElem,sorted);
});
上記のorderByの書き方で、sortTypeとsortDest、sortTypeAltとsortDestAltがそれぞれ対となって指定した順番に優先的にソートされます。
今回では 日付昇順・ID昇順が一番自然な並びとなります。
まとめ
Lodashには今回紹介した以外にも膨大な関数が用意されています。
特にthrottleやdebounceは、関数の実行を間引くことができるので、ウインドウのリサイズ処理で使用する事でより軽快な動きを実現させたりすることができます。
まだまだJavaScriptをゴリゴリ書いていかねばならない人は、ぜひ使ってみて下さい。