課程目標

認識 data model 的觀念

認識 render function 的觀念

課程內容

如果電商網站上有這樣的內容

<div>
  商品名稱:<span id="name">冬季外套</span>
  價格:<span id="price">$1,990</span>
  分類:<span id="category">女裝</span>
  剩餘數量:<span id="remain">5</span>
</div>

在網站上的任何操作,菜鳥工程師會覺得就直接去更新 DOM 就好了

在程式還小的時候,這樣開發沒問題

但是當專案變大之後,這樣的開發會遇到問題,程式碼會越來越難維護

這種很難維護的寫法,我稱之為「在各處胡亂更新各處 DOM」的寫法


有經驗的工程師在開發的時候,會習慣將應用程式的「狀態」與程式的其他部份分開來

這個「狀態」我們叫 state 或者 model 或者 data model

實務上,這三種名詞都很常看到,我在文章中也會混雜著交互使用

同樣的電商頁面,資深工程師會覺得看到了以下 data model

var product = {
  name: "冬季外套",
  price: 1990,
  category: "women",
  remain: 5
}

而在開發各種功能的時候,資深工程師會覺得,一律先更新 data model,再接著拿 data model 來呈現出 UI 比較好

這樣在開發複雜應用程式的時候,相關函式一律只要關心 data model 就好,不用管 UI

在思考的時候,腦子的負擔會小很多,因為你變得只要想著應用程式的「狀態」就好


那麽只更新 data model,那何時更新 UI 呢?

這邊介紹一個簡單的方法,叫做 render function

就是放一個 root 元素,作為程式 UI 的容器

接著寫一個 render 函式,來根據 data model,畫出全部 UI 到 root 裡面

這個 render 函式有三個注意事項

  • 第一行要先清空 UI
  • 在所有跟「狀態」有關操作的最後一行,都要呼叫這個函式
  • 所有 DOM 操作一律由 render 函式處理(其他全部函式,通通禁止更新 DOM)

請在 jsfiddle 嘗試以下範例

<div id="root">

</div>
<button onclick="decrease()">decrese</button>
<button onclick="increase()">increase</button>
var product = {
  name: "冬季外套",
  price: 1990,
  category: "women",
  remain: 5
};

render();

function render()
{
  var root = document.querySelector('#root');
  root.textContent = "";

  var name = document.createElement('div');
  name.textContent = '商品名稱:' + product.name;
  var price = document.createElement('div');
  price.textContent = '價格:' + product.price;
  var category = document.createElement('div');
  category.textContent = '分類:' + product.category;
  var remain = document.createElement('div');
  remain.textContent = '剩餘數量:' + product.remain;

  root.append(name);
  root.append(price);
  root.append(category);
  root.append(remain);
}

function decrease()
{
  product.remain = product.remain - 1;

  render();
}

function increase()
{
  product.remain = product.remain + 1;

  render();
}

這樣的寫法,很神奇地,關於 DOM 的操作通通放在 render 即可

雖然 render 函式變得很多行、很大、寫起來比較麻煩

但是除了 render 以外的函式,通通都變簡單了

這是「短期麻煩,長期方便」的一個明顯例子

課後作業

在之前的課程,你開發過一個「待辦事項小工具」,甚至還加上了 local storage 儲存功能

在開發的過程中,我相信你有感覺到,程式碼越來越大團了,新功能雖然寫得出來,但越來越難寫了

回頭看看當初的程式碼,你會發現讀起來不容易,要再維護、擴充功能,也都不太容易

讓我們使用新方法,重新開發一次這個小工具

請使用 https://jsfiddle.net 並且建立一份新的 fiddle


這一課,不開發任何功能,先實作把 data model 給 render 出來的效果

請使用以下 html 作為 root 元素

<div id="root">
</div>

然後複製以下 js 使用,將 render 函式完成

var todos = [
  {
    title: "倒垃圾"
  },
  {
    title: "繳電話費"
  },
  {
    title: "採買本週食材"
  },
];

function render()
{
  // 請寫出此函式內容
}

render();

在這段 js 中,todos 陣列,就是我們的 data model

最後,在畫面上,應該會出現以下內容

<div id="root">
  <ul>
    <li>
        <span>倒垃圾</span>
    </li>
    <li>
        <span>繳電話費</span>
    </li>
    <li>
        <span>採買本週食材</span>
    </li>
  </ul>
</div>

做出以上功能,你就完成這次的課程目標了!


歡迎將作業成果,在下方留言,跟大家分享,讓大家給你一些回饋!

可以將每課學到的觀念、關鍵字,丟到網路上去搜尋、研究一下!

發問請在「討論專區」為主,或者分享學習筆記、寫學習心得!

貼文都會出現在個人檔案頁面,成為學習歷程、部落格紀錄!

未來面試時,分享給面試官看,會讓人知道你的積極程度!

按讚的人:

共有 22 則留言

交作業 https://jsfiddle.net/birdie2019/7haz6fLj/9/

按讚的人:

寫得很好,順利完成!

for (var item of todos)

這段寫法好棒喔 我還傻傻地用<length哈哈哈 學到惹

按讚的人:

從這一課學到的 https://codelove.tw/@howtomakeaturn/post/Aq5Agq 我也覺得這方法很棒!

按讚的人:

酷喔雖然沒搞過 但我覺得我馬上就能懂 而且知道怎麼做 因為我玩過串API 所以能感覺 這是為了方便後端更新數據 引發的的概念 資料不要寫死 隨時就可以改

頁面上只要留一串假資料(或甚至不需要)的概念

原來我早就懂data model 與 render function了耶 現在瞭解這術語 感覺自己好強喔XDD

按讚的人:

阿對了,應該也是因為我常常在練習寫油猴腳本,用到的都是JS, 所以也很習慣把html用JS去動態產生XDD 對這個想法完全能融入 好讚!

按讚的人:

作業繳交 https://jsfiddle.net/hr7fyoav/3/

按讚的人:

寫得很好,順利完成!

交作業 https://jsfiddle.net/superyngo/f3jzo49d/2/

好像應該先研究一下bootsratp 不然處理樣式真的花時間

按讚的人:

寫得很好,順利完成!

按讚的人:

交作業 https://jsfiddle.net/evon0306/k5vpeza8/

按讚的人:

寫得很好,順利完成!

按讚的人:

交作業,再麻煩站長了,謝謝! https://jsfiddle.net/jm85xqnL/

按讚的人:

學了關注點分離的術語再重新回來看這篇 寫得非常讚 很清楚

按讚的人:

https://jsfiddle.net/wimp9487/tvxLhbgy/7/ 交作業!

按讚的人:

https://jsfiddle.net/ZooeyLai/jpdc8meh/1/ 交作業~

按讚的人:

寫得很好,順利完成!

作業繳交

https://jsfiddle.net/mb2902911/ak9t1nzL/1/

按讚的人:

交作業 https://codepen.io/adens123/pen/BaMJjvg

按讚的人:

交作業了 https://jsfiddle.net/eoL0km74/

按讚的人:

交作業了 ~ https://jsfiddle.net/erika_sun/v9rp1f3k/13/

按讚的人:

2024.02.15 https://jsfiddle.net/xgpmrw3j/

按讚的人: