概要
前回”Pug”とは何なのか、簡単ではありますが、説明させていただきました。
今回は、Pugで記述されたテンプレートファイルを元に、JQueryの値埋め込み処理を記述する例を自分用にメモとして残します
前提
システム開発において、固定値で画面が作成される、なんてことはありえないです
jsのソースコードに、動的に値をDOMに埋め込んでいく実装を進めていくと思いますが、Pug記法を使用することはできない
(=Pugは、あくまでHTMLのテンプレートエンジン)
ステップ1
index.js
JQueryで値を動的にHTMLに対して設定する例として、まず思いつくのは
- モック画面を開発者ツールなどで調べ、明細部のHTMLをコピー
- それをjs部分に貼り付けて、テンプレートリテラルなどを使って、値を設定する
感じでしょうか。私のレベルはここでした。。。
$(function() {
// APiリクエストなどして取得したデータ例
var list = [
{
date:"2022/09/03",
memo:"",
name:"枝豆"
},
{
date:"2022/09/03",
memo:"hogehoge",
name:"ビール"
}
]
// 元のHTMLを開発者ツールなどで、取得してくる
list.forEach((elem, index) => {
var dom = `
<div class="activity-table-tr">
<div class="activity-table-td-left">
<div class="activity-table-td--date">${elem.date}</div>
<div class="activity-table-td--name">${elem.name}</div>
</div>
<div class="activity-table-td-right">
<div class="activity-table-td--memo">${elem.memo}</div>
</div>
</div>
`
$(".activity-table-body").append(dom)
})
});
これで全然実装できます。
ただ、このやり方の問題点としては、
- データの操作をしたいだけなのに、見た目の実装に深く依存している
- UI変更(クラス名や、HTML要素の変更)が発生したとき、非常に困難な修正となる
っと、行った感じで、”力技”感は否めませんよね
ステップ2
特徴
- jsファイルに、HTML要素(や、クラス名{見た目に影響するようなもの}の記述を極力行わない
- データ操作、に着目する観点で、データ属性を付与し、それを中心に検索・操作する
- Pugファイル=テンプレート、の観点で、テンプレートを複製し、複製したDOMに対して操作する
Pugファイル(Before)
doctype html
html(lang="ja")
head
title タイトル
meta(charset='utf-8')
meta(http-equiv="X-UA-Compatible", content="IE=edge,chrome=1")
meta(name="viewport", content="width=device-width, initial-scale=1")
block link
link(rel='stylesheet', href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css")
body
.container
button.btn.
api request
hr
h1#heading タイトル
hr
.activity-table
.activity-table-body
each item in list
.activity-table-tr
.activity-table-td-left
.activity-table-td--date=item.date
.activity-table-td--name=item.name
.activity-table-td-right
.activity-table-td--memo=item.memo
hr
block end_of_body
script(src="https://code.jquery.com/jquery-3.6.1.min.js")
script(src="./index.js")
Pugファイル(After)
"data-js-text={XXXX}"に着目してみてください
データ操作用のデータ属性を付与しています
... 省略
h1#heading タイトル
hr
.activity-table
.activity-table-body
.activity-table-tr(data-js-each="table-list-items")
.activity-table-td-left
.activity-table-td--date(data-js-text="date")
.activity-table-td--name(data-js-text="name")
.activity-table-td-right
.activity-table-td--memo(data-js-text="memo")
hr
block end_of_body
script(src="https://code.jquery.com/jquery-3.6.1.min.js")
script(src="./index.js")
index.js
いかがでしょうか。
HTML要素の記述は、極力なくせたと思います。
$(function() {
// APiリクエストなどして取得したデータ例
var list = [
{
date:"2022/09/03",
memo:"",
name:"枝豆"
},
{
date:"2022/09/03",
memo:"hogehoge",
name:"ビール"
}
]
// データ属性指定で、繰り返すDOMを取得する
var templateOriginal = $("[data-js-each=table-list-items]")
// 複製元のDOMを非表示にする(Pugファイルに記載されているのはあくまで”テンプレート”として活用する)
templateOriginal.hide()
list.forEach((item, index) => {
// data属性指定で、複製したDOMを操作する
// 下記、メソッド化してさらにスマートにできそうですね!
var template = templateOriginal.clone().wrap('<div>').parent()
template.find('[data-js-text=date]').each((_, elem) => {
$(elem).text(item.date)
})
template.find('[data-js-text=name]').each((_, elem) => {
$(elem).text(item.name)
})
template.find('[data-js-text=memo]').each((_, elem) => {
$(elem).text(item.memo)
})
// 操作したDOMを、指定した箇所の最後に追加して、表示する
template.children().insertAfter("[data-js-each=table-list-items]:last").show()
})
});
まとめ
Pug記法で記述されたモックを基に、動的な処理を実装していく、という想定で説明しましたが、Pug記法で書いてる書いてない、にかかわらず、データ属性で操作していく”ステップ2”は、私のベストプラクティスかなと思います
いやいや、もっとスマートにかけるよ!という世の諸先輩方はぜひあなたのベストプラクティスをご教示ください!
ではまた!