【AJAX 实战】图书管理系统上 渲染图书列表+新增图书+删除图书
文章目录
- 1.渲染图书列表
- 2.新增图书
- 2.1 使用serialize收集表单数据
- 2.2 提交到服务器中保存
- 2.3 重新渲染页面,重置表单 隐藏弹框
- 3.删除图书
- 3.1 绑定删除按钮点击事件->获取图书 id
- 3.2 调用删除接口+刷新图书列表
1.渲染图书列表
为什么要渲染图书列表?
通过接口文档,不难发现,获取图书列表需要的请求参数为creator,这里随意即可
因为后期增删改查的时候,每做完一次增删改查之后,需要刷新页面,才能实时的展示出来
function getBooksList(){// 1.1 获取数据//axios 默认是 get 方法axios({url:'http://hmajax.itheima.net/api/books',params:{creator:'小王'}}).then(result=>{console.log(result)})
}
//网页加载运行,获取并渲染列表一次
getBooksList()
console.log 结果如下:
通过 result.data.data 能够取到待渲染的数组
// 1.2 渲染数据const htmlStr = bookList.map(item => {return ` <tr><td>1</td><td>JavaScript程序设计</td><td>马特·弗里斯比</td><td>人民邮电出版社</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr>`}).join('')console.log(htmlStr)
.map方法
map() 是数组的方法,意思是对数组的每一项执行一次函数”,返回一个新数组。其中item 是每一次遍历的当前元素(每一本书)
.join 方法
- map() 返回一个数组(数组里都是 HTML 字符串)
- join(‘’) 是将这个数组合并成一个字符串,之间不加任何连接符(即:空字符串 ‘’)
console 打印如下:
将该列表渲染到表格上
document.querySelector(".list").innerHTML=htmlStr
修改模板字符串:
const htmlStr = bookList.map((item,index) => {return ` <tr><td>${index+1}</td><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr>`
完整封装代码如下:
function getBooksList() {// 1.1 获取数据//axios 默认是 get 方法axios({url: 'http://hmajax.itheima.net/api/books',params: {creator: '小王'}}).then(result => {console.log(result)const bookList = result.data.dataconsole.log(bookList)// 1.2 渲染数据const htmlStr = bookList.map((item,index) => {return ` <tr><td>${index+1}</td><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr>`}).join('')console.log(htmlStr)document.querySelector(".list").innerHTML=htmlStr})
}//网页加载运行,获取并渲染列表一次
getBooksList()
2.新增图书
新增图书总逻辑:
1.使用serialize收集表单数据
2.提交到服务器中保存
3.添加成功后,重新渲染表单 重置表单 隐藏弹框
2.1 使用serialize收集表单数据
//获取弹框对象
const addModalDom = document.querySelector('.add-modal')
const addModal = new bootstrap.Modal(addModalDom)//新增图书保存按钮,绑定收集表单元素的事件
document.querySelector('.add-btn').addEventListener('click',()=>{
const addForm = document.querySelector('.add-form')
const bookObj=serialize(addForm,{hash:true,empty:true})
console.log(bookObj)
2.2 提交到服务器中保存
使用 axios 将数据提到服务端
新增图书接口文档如下:
// 1.使用serialize收集表单数据
const addModalDom = document.querySelector('.add-modal')
const addModal = new bootstrap.Modal(addModalDom)document.querySelector('.add-btn').addEventListener('click',()=>{const addForm = document.querySelector('.add-form')const bookObj=serialize(addForm,{hash:true,empty:true})// console.log(bookObj)axios({url:'http://hmajax.itheima.net/api/books',method:'POST',data :{...bookObj,creator}}).then(result=>{console.log(result)})
2.3 重新渲染页面,重置表单 隐藏弹框
在 axios 中的 then 中重新渲染表单,同时渲染完成后应该隐藏表单
axios({url:'http://hmajax.itheima.net/api/books',method:'POST',data :{...bookObj,creator}}).then(result=>{console.log(result)//重新渲染图书列表getBooksList()//隐藏弹框addModal.hide()})
但是,再重新点击新增按钮后,发现表单上仍存在着原来的数据如下:
axios({url:'http://hmajax.itheima.net/api/books',method:'POST',data :{...bookObj,creator}}).then(result=>{console.log(result)//重新渲染图书列表getBooksList()// 重置表单addForm.reset()//隐藏弹框addModal.hide()})
完整的新增表单的 js 如下:
const addModalDom = document.querySelector('.add-modal')
const addModal = new bootstrap.Modal(addModalDom)document.querySelector('.add-btn').addEventListener('click',()=>{const addForm = document.querySelector('.add-form')const bookObj=serialize(addForm,{hash:true,empty:true})// console.log(bookObj)axios({url:'http://hmajax.itheima.net/api/books',method:'POST',data :{...bookObj,creator}}).then(result=>{console.log(result)//重新渲染图书列表getBooksList()// 重置表单addForm.reset()//隐藏弹框addModal.hide()})})
3.删除图书
3.1 绑定删除按钮点击事件->获取图书 id
事件委托
为什么不绑定删除按钮,而是绑定他的父元素list,因为list是写死的,del删除按钮是后期渲染的,假如渲染del就会需要很多的监听器,而渲染 list,一个就可以监听
document.querySelector('.list').addEventListener('click',e=>{console.log(e.target)
})
常用的事件对象的属性中有 e.target,获取事件被点击的对象,常用于事件委托.
e.target常用操作
- e.target.classList
一个用于操作元素类名(class)的对象
e.target.classList.contains('del') // 是否有某个类
e.target.classList.add('active') // 添加类
e.target.classList.remove('hide') // 移除类
e.target.classList.toggle('on') // 有就删,没有就加
- e.target.innerText/innerHTML
获取/修改标签内的文本或 HTML 内容
console.log(e.target.innerText) // 纯文本内容
console.log(e.target.innerHTML) // 包括标签的内容
- e.target.value
用于获取 input、textarea 的值(仅限表单类元素)
if (e.target.tagName === 'INPUT') {console.log(e.target.value) // 输入框的值
}
获取图书 id(自定义属性 id)
在渲染模板代码的时候,不难发现其中就有 id,所以用 item.id 就能得到 id,然后讲 id 值放入到渲染的标签中,然后通过 e.target 就可以得到 id 值
假设把 id 值放入到删除按钮中
<tr><td>${index+1}</td><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td ><span class="del" data-id=${item.id}>删除</span><span class="edit">编辑</span></td>
</tr>
点击删除按钮即可看到 id 值,然后通过方法即可取到 id 值,但是这样会导致一个问题,使用编辑操作的时候也要 id 值,所以应该把这个 id 写在这两个按钮的父亲标签 td 中
<tr><td>${index+1}</td><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td data-id=${item.id}><span class="del">删除</span><span class="edit">编辑</span></td>
</tr>
打印点击元素的父节点
console.log(e.target.parentNode)
不管是点击删除还是编辑都能看到 td 标签了
HTML 允许我们给标签添加以 data- 开头的属性,比如:
<td data-id="123" data-book-name="Vue实战"></td>
然后通过 js进行访问 .dataset.(-后面名称),就可以拿到这个值
const td = document.querySelector('td')
console.log(td.dataset.id) // 输出:"123"
console.log(td.dataset.bookName) // 输出:"Vue实战"
项目代码如下:
document.querySelector('.list').addEventListener('click',e=>{// console.log(e.target)const theId=e.target.parentNode.dataset.id// console.log(e.target.parentNode)console.log(theId)//调用删除接口
})
3.2 调用删除接口+刷新图书列表
接口文档如下:
注意模板字符串 url 是反引号,注意判断是否为删除按钮
//如果是删除按钮if(e.target.classList.contains('del')){// console.log(e.target)const theId=e.target.parentNode.dataset.id// console.log(e.target.parentNode)console.log(theId)//调用删除接口axios({url:`http://hmajax.itheima.net/api/books/${theId}`,method:'DELETE'}).then(()=>{getBooksList()})}
完整删除图书 js 代码如下:
//删除图书逻辑
// 1.绑定删除按钮点击事件->获取图书 id
// 2.调用删除接口
// 3.刷新图书列表document.querySelector('.list').addEventListener('click',e=>{//如果是删除按钮if(e.target.classList.contains('del')){// console.log(e.target)const theId=e.target.parentNode.dataset.id// console.log(e.target.parentNode)console.log(theId)//调用删除接口axios({url:`http://hmajax.itheima.net/api/books/${theId}`,method:'DELETE'}).then(()=>{getBooksList()} )}
})