如何修改IndexedDB示例代码以删除列表中最后添加的条目
解决方案
错误原因分析
你之前的实现混淆了DOM操作和IndexedDB的存储操作:removeChild是用于操作页面DOM节点的API,不能直接作用于IndexedDB的对象仓库,IndexedDB有独立的增删改查API。另外原有代码的书籍对象仓库没有记录添加时间,getAll()默认按主键(书名)排序,无法直接识别最后添加的条目。
具体修改步骤
- 调整书籍存储结构,新增添加时间戳字段,用于识别插入顺序
- 新增删除最后一条条目的页面操作按钮
- 实现删除逻辑:查询所有书籍后按添加时间排序,取最后一条调用IndexedDB的
delete接口删除对应条目
完整修改后代码
<!doctype html> <script src="https://cdn.jsdelivr.net/npm/idb@3.0.2/build/idb.min.js"></script> <button onclick="addBook()">Add a book</button> <button onclick="clearBooks()">Clear books</button> <!-- 新增删除最后一条的按钮 --> <button onclick="deleteLastBook()">删除最后添加的书籍</button> <p>Books list:</p> <ul id="listElem"></ul> <script> let db; init(); async function init() { // 数据库版本号升级为2,兼容旧存储结构 db = await idb.openDb('booksDb', 2, db => { if (!db.objectStoreNames.contains('books')) { db.createObjectStore('books', {keyPath: 'name'}); } }); list(); } async function list() { let tx = db.transaction('books'); let bookStore = tx.objectStore('books'); let books = await bookStore.getAll(); if (books.length) { listElem.innerHTML = books.map(book => `<li> name: ${book.name}, price: ${book.price} </li>`).join(''); } else { listElem.innerHTML = '<li>No books yet. Please add books.</li>' } } async function clearBooks() { let tx = db.transaction('books', 'readwrite'); await tx.objectStore('books').clear(); await list(); } async function addBook() { let name = prompt("Book name?"); let price = +prompt("Book price?"); let tx = db.transaction('books', 'readwrite'); try { // 新增createTime字段记录添加时间戳 await tx.objectStore('books').add({name, price, createTime: Date.now()}); await list(); } catch(err) { if (err.name == 'ConstraintError') { alert("Such book exists already"); await addBook(); } else { throw err; } } } // 新增删除最后添加书籍的逻辑 async function deleteLastBook() { let tx = db.transaction('books', 'readwrite'); let bookStore = tx.objectStore('books'); let allBooks = await bookStore.getAll(); if (allBooks.length === 0) { alert('当前没有可删除的书籍'); return; } // 按添加时间升序排序后取最后一条,即为最后添加的书籍 let lastBook = allBooks.sort((a, b) => a.createTime - b.createTime).pop(); // 调用IndexedDB的delete方法,传入主键(书名)删除对应条目 await bookStore.delete(lastBook.name); await list(); } window.addEventListener('unhandledrejection', event => { alert("Error: " + event.reason.message); }); </script>
内容的提问来源于stack exchange,提问作者Adam Gong
相关产品推荐
相关产品推荐

