表示とデータを切り分ける
このレッスンで分かること
- 画面に出す値を組み立てる仕事を、DOM をさわる関数から切り離します
- 値の読み替えは
ifを並べず、対応表のオブジェクトで持ちます
文字列が正しいかを、画面を描かないと確かめられない
入門で書いた createWorkCard をもう一度見ます。
JavaScript
function createWorkCard(work) {
const card = document.createElement("article");
if (work.views >= 100) {
card.classList.add("featured");
}
const heading = document.createElement("h3");
heading.textContent = work.title;
card.append(heading);
return card;
}この関数は 2 つの仕事をしています。1 つは「views が 100 以上なら注目扱いにする」という データについての判断。もう 1 つは createElement と append を呼ぶ 画面についての操作 です。
この 2 つが同じ場所にあると、判断が正しいかを確かめるのに、いちいち画面を描かせるしかありません。同じ判断を一覧表でも使いたくなればコピーすることになり、データに項目が増えれば DOM を組む関数まで開くことになります。
そこで、判断と組み立てだけを担う関数を 1 本切り出します。データを受け取り、画面に出したい値だけを持つ別のオブジェクトを返す関数です。このコースではこれを ビューオブジェクト と呼びます。DOM を一度もさわらないので、戻り値を console.log で見るだけで正しさを確かめられます。
読み替えは if ではなく表で持つ
内部の値を日本語のラベルに読み替えるとき、if を並べたくなります。値が 3 つのうちは動きますが、増えるたびに分岐が伸びます。オブジェクトを対応表として使うと 1 行で書けます。
JavaScript
const LEVEL_LABELS = {
basic: "基礎",
mid: "実務",
high: "得意"
};
console.log(LEVEL_LABELS["mid"]); // "実務"
console.log(LEVEL_LABELS["none"]); // undefined表に無い値を渡すと undefined が返ります。そのまま画面に出すと undefined という文字が並ぶので、|| で受け止めます。
JavaScript
const label = LEVEL_LABELS[skill.level] || "未設定";同じ考えかたで、配列の項目が欠けているときも受け止めます。undefined のまま join を呼ぶと TypeError で処理全体が止まるためです。
JavaScript
const topics = skill.topics || [];
console.log(topics.join(" / ")); // 項目が無ければ ""|| は左が falsy なときに右を返します。空配列は truthy なので、[] のときは [] がそのまま使われ、join の結果は空文字になります。狙いどおりです。
名前が変わるところに設計がある
ビューオブジェクトでは、項目の名前も付け替えます。たとえば published は「作者が公開したかどうか」というデータの事実で、画面側で要るのは「この一覧に出すかどうか」という表示の判断です。いまは同じ値ですが、あとで「下書きも管理画面では見せる」となったとき、変わるのは表示側の項目だけで済みます。
数値どうしをつないだ 1 行の文字列も、画面のためだけの値です。データは year と views を別々に持ち続け、つないだ結果はビューオブジェクトが持つ。この線を引いておくと、データの出どころが API に変わっても描画側を書き直さずに済みます。
よくある間違い
- 変換関数の中で DOM をさわる — 1 行でも
documentが出てきたら、それはもう変換関数ではありません。戻り値だけで確かめられなくなります - 元のデータを書き換えてしまう — 変換のついでに引数のオブジェクトへ項目を足すと、元の配列が汚れます。新しいオブジェクトを作って返してください
JavaScript
// 誤り。引数のオブジェクトを書き換えている
function toSkillRow(skill) {
skill.label = LEVEL_LABELS[skill.level];
return skill;
}- 未設定の項目をそのまま使う — 項目を持たないデータが 1 件でも混ざると、そこで処理全体が止まります。外から取ってきたデータには、項目が欠けている行がふつうに混ざります
要件
- 関数名は
toWorkView、引数は作品データのオブジェクトworkを 1 つだけ受け取る - 戻り値は
{ id, title, meta, categoryLabel, tagText, visible }の 6 項目を持つ新しいオブジェクトにする metaはwork.yearとwork.viewsから2026 年 / 120 回表示の形の文字列を組み立て、categoryLabelはsiteをサイト、cardをカード、tableを表に読み替える。それ以外と未設定はその他にするtagTextはwork.tagsを/でつないだ文字列にする。work.tagsが未設定のときは空文字を入れてエラーで止めない。visibleはwork.publishedがtrueのときだけtrueにする