0%

Node.js - 寫一個簡單的 TodoList:刪除資料

node

有新增就有刪除,延續前篇的 TodoList 新增功能,當然也需要一個刪除功能。

前情提要

已經完成一個新增功能的代辦功能開發,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// DOM

let memo = document.querySelector("#memo");
const btn = document.querySelector("#btn");
const list = document.querySelector("#list");

// data
const todo = firebase.database().ref("todo");

// click
btn.addEventListener("click", function (e) {
console.log(memo.value); //確認取得 input 的值
//* 把 input 的值新增到 Firebase
todo.push({ content: memo.value });
});

// on

todo.on("value", function (snapshot) {
console.log(snapshot.val()); //* 確認從資料庫取回的內容
let str = "";
let data = snapshot.val();
for (let item in data) {
console.log(data[item]); //* 如果只取 item 會是資料庫的 key
str += `<li>${data[item].content}</li>`; //* 累加列表
}
console.log(str); // 確認取得 <li>xxxx</li> 的標籤
list.innerHTML = str;
memo.value = ""; //* 按下送出後,清空 input 的值
});

接著要來開發刪除功能,

使用子路徑來完成刪除待辦事項

刪除功能想要是選到該筆待辦事項後隨即刪除,所以會是使用 click 事件,那我要點在 li 上,目前也綁定 ul,而 li 是透過動態產生的元素,所以先在 ul 上面監聽點擊事件,

firebase.js

1
2
3
list.addEventListener("click", function (e) {
console.log(e);
});

這邊就跟寫平常的 JavaScript 感覺一樣了,透過 console 可以看到 click 事件中有很多屬性可以選,當然要選擇元素的屬性是 target,然後要選到節點名稱為 LI

1
2
3
4
5
// 刪除

list.addEventListener("click", function (e) {
console.log(e.target.nodeName === "LI"); // true
});

這邊選到了以後可以將此結果當成判斷結果,

firebase.js

1
2
3
4
5
6
7
// 刪除

list.addEventListener("click", function (e) {
if (e.target.nodeName === "LI") {
// 刪除資料
}
});

但這邊問題來了,我怎麼知道現在的 li 是哪一筆 li

使用 key 值

這邊看一下資料庫的畫面,

db

有提到過每一筆資料都個 key 值,且是唯一性,可以使用這個 key 值當作每筆資料的 id,此時要先在新增的 li 元素中加上 data-key 的屬性,並把 key 值放到 li 上。

firebase.js

1
2
3
4
5
6
7
8
9
10
11
12
todo.on("value", function (snapshot) {
console.log(snapshot.val());
let str = "";
let data = snapshot.val();
for (let item in data) {
console.log(data[item]); //* 如果只取 item 會是資料庫的 key
str += `<li data-key="${item}">${data[item].content}</li>`; //* key 加在動態產生的 li 上
}
console.log(str); // 確認取得 <li>xxxx</li> 的標籤
list.innerHTML = str;
memo.value = ""; //* 按下送出後,清空 input 的值
});

完成後可以透過開發人工具看看在 li 標籤上有沒有出現動態產生的 data-key

key

看起來是有成功的,

透過 key 刪除該筆待辦事項

再來一樣從 click 事件裡面找到有關於選到 li 會出現 key 的屬性,

key

看起來是 e.target.dataset.key,把這個屬性複製用一個變數存取,最後在用仔路徑的方式取得此 key 後刪除。

firebase.js

1
2
3
4
5
6
7
//刪除
list.addEventListener("click", function (e) {
if (e.target.nodeName === "LI") {
const key = e.target.dataset.key;
todo.child(key).remove();
}
});

完整程式碼

firebase.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
et memo = document.querySelector("#memo");
const btn = document.querySelector("#btn");
const list = document.querySelector("#list");

// data
const todo = firebase.database().ref("todo");

// click
btn.addEventListener("click", function (e) {
console.log(memo.value); //確認取得 input 的值
//* 把 input 的值新增到 Firebase
todo.push({ content: memo.value });
});

// on

todo.on("value", function (snapshot) {
console.log(snapshot.val());
let str = "";
let data = snapshot.val();
for (let item in data) {
console.log(data[item]); //* 如果只取 item 會是資料庫的 key
str += `<li data-key="${item}">${data[item].content}</li>`; //* 累加列表
}
console.log(str); // 確認取得 <li>xxxx</li> 的標籤
list.innerHTML = str;
memo.value = ""; //* 按下送出後,清空 input 的值
});

// 刪除

list.addEventListener("click", function (e) {
if (e.target.nodeName === "LI") {
const key = e.target.dataset.key;
todo.child(key).remove();
}
});

Demo