iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
ChatGPT & Codex

從需求到實作:30 天與 Codex 協作打造 Idea Note PWA系列 第 8

Day 8|每則筆記都有刪除按鈕,程式怎麼知道我要刪哪一則?

  • 分享至 

  • xImage
  •  

昨天把新增筆記後的操作收尾,讓輸入框可以自動清空,並且把游標放回輸入框。

今天開始處理另一個核心功能:刪除筆記。

在畫面上放一個刪除按鈕不難,真正需要處理的是,當頁面上同時有很多則筆記時,程式要怎麼知道使用者想刪除的是哪一則?

總不能按下其中一個刪除按鈕,結果整個清單一起消失。

這次給 Codex 的需求

為了延續前幾天「一次只處理一件事」的方式,我把這次的任務限制在刪除功能:

請替每一則筆記加入刪除按鈕。使用者點擊後,只刪除對應的那一則資料,再重新顯示筆記清單。這次不要加入編輯功能。

這次要確認的不只是按鈕有沒有出現,還要實際測試刪除第一則、中間一則和最後一則筆記時,結果是否都正確。

為什麼不能直接用筆記內容判斷?

假設目前有兩則內容完全相同的筆記:

[
  {
    id: 101,
    content: "記得買牛奶"
  },
  {
    id: 102,
    content: "記得買牛奶"
  }
]

如果程式只根據文字判斷,很可能無法分辨使用者到底想刪除哪一則。

所以前面建立筆記資料時加入的 id,現在終於派上用場。

即使兩則筆記的內容完全相同,只要 id 不同,程式就能把它們視為兩筆獨立資料。

讓每個按鈕記住自己的筆記編號

產生筆記畫面時,每一則筆記都會建立自己的刪除按鈕。

const deleteButton = document.createElement("button");

deleteButton.textContent = "刪除";

deleteButton.addEventListener("click", () => {
  deleteNote(note.id);
});

當使用者點擊按鈕時,程式會把目前這則筆記的 id 傳給 deleteNote()

這樣每個刪除按鈕看起來雖然一樣,背後帶入的編號卻不同。

第一則筆記的按鈕可能傳入 101,第二則則傳入 102。程式因此能確定使用者真正選中的是哪一筆資料。

使用 filter() 留下其他筆記

取得目標 id 後,可以利用陣列的 filter() 移除指定資料:

function deleteNote(id) {
  notes = notes.filter((note) => note.id !== id);
}

這段程式不是直接找到某一筆資料並把它拔掉,而是重新建立一個陣列。

它會逐一檢查每則筆記:

  • id 不等於目標編號的筆記,留下來
  • id 等於目標編號的筆記,不放進新陣列

最後得到的結果,就是少了指定筆記的新清單。

我以前看到 filter() 時,總覺得「篩選」和「刪除」是兩件不同的事。

放進這個功能後就比較容易理解:刪除指定資料,也可以換個方向思考成「只留下其他資料」。

這裡遇到 constlet 的差別

原本如果使用 const 宣告筆記陣列:

const notes = [];

就不能再將一個新的陣列指定給 notes

notes = notes.filter((note) => note.id !== id);

因為 filter() 會回傳新的陣列,而 const 宣告的變數不能被重新指定。

如果採用這種刪除方式,筆記陣列就要改成:

let notes = [];

這不是因為陣列內容會改變,所以一定要使用 let

真正的原因是,這裡會將 notes 重新指定成另一個陣列。

這個差別很小,但如果沒有檢查 Codex 修改的內容,我可能只會看到 const 突然變成 let,卻不知道它為什麼要改。

資料刪除了,畫面也要更新

執行 filter() 後,陣列裡的資料已經改變,但畫面不會自己跟著更新。

因此,刪除完成後還要重新執行顯示筆記的函式:

function deleteNote(id) {
  notes = notes.filter((note) => note.id !== id);
  renderNotes();
}

如果只修改陣列,卻沒有再次呼叫 renderNotes(),使用者仍然會看到那則筆記留在畫面上。

這時就會出現一個很奇怪的狀態:畫面看起來沒有刪除成功,但程式裡其實已經找不到那筆資料。

所以每次資料發生變化後,都要記得同步更新畫面。

刪除前要不要再次確認?

刪除和新增不太一樣。

新增錯了,之後還有機會修改;但如果誤觸刪除按鈕,目前又沒有復原功能,那則筆記就會直接消失。

第一版最簡單的作法,是先使用瀏覽器內建的確認視窗:

const confirmed = window.confirm("確定要刪除這則筆記嗎?");

if (!confirmed) {
  return;
}

使用者按下取消時,函式會停止;只有按下確定,才會繼續刪除資料。

瀏覽器內建視窗的外觀不一定好看,但目前比立刻製作一個自訂對話框簡單,也可以先避免誤刪。

等主要功能完成後,再決定要不要換成符合 Idea Note 風格的確認視窗。

今天要測試的不只是「能刪除」

這次至少需要測試以下情況:

  1. 只有一則筆記時進行刪除。
  2. 多則筆記中刪除第一則。
  3. 多則筆記中刪除中間一則。
  4. 多則筆記中刪除最後一則。
  5. 有相同內容時,只刪除選中的那一則。
  6. 在確認視窗按下取消,筆記不能消失。
  7. 刪除後,其他筆記仍然正常顯示。

其中最重要的是相同內容的測試。

如果兩則「記得買牛奶」只消失了被點選的那一則,就表示程式真正依靠的是 id,而不是畫面上的文字。

今天完成的不只是一個刪除按鈕,而是讓每個按鈕都能找到自己對應的資料。

下一篇,我會開始處理編輯功能,讓使用者可以修改原本的筆記,而不是每次寫錯都只能刪掉重來。


上一篇
Day 7|新增成功還不夠:讓使用者可以立刻寫下一則筆記
下一篇
Day 9|按下儲存時,程式怎麼知道我要新增還是修改?
系列文
從需求到實作:30 天與 Codex 協作打造 Idea Note PWA10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言