与之前的功能一样,但是引入mvc把代码模块化了。
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
<title> axios test</title>
</head>
<body>
<div id="app">
</div>
<script src="./main.js"></script>
</body>
</html>
js:
//用ajax获取一个数据
fakeData()
//引入mvc 的 model
let model = { //所有数据相关的操作都在model里面实现
data:{
name:'',
number:0,
id:''
},
fetch(id){ //获取数据,用id去获取
return axios.get(`/books/${id}`).then(({response}) => {
this.data = response.data
return response
})
},
update(data){ //更新数据,也要用id去获取,但用data去更新
this.id = this.data.id
return axios.put(`books/${id}`,data}).then((response)=>{
this.data = response.data
return response
})
}
}
//引入mvc 的 view
let view = {
el: '#app',
template: `
<div>
书名:---name---
数量:<span id="number">---number---</span>
</div>
<div>
<button id="add1">+ 1</button>
<button id="remove1">- 1</button>
<button id="reset">归 0</button>
</div>
`
render(){ //初始化html,如何去更新这个 view
let html = this.template.replace('---name---',data.name)
.replace('---number---',data.number)
$(this.el).html(html)
}
}
//引入mvc 的 controller
var conreoller = {
init(options){
let view = options.view
let model = options.model
this.view = view
this.model = model
this.view.render(this.model.data)
this.bindEvents()
//使用这个数据更新html里的内容
model.fetch(1)
.then(() => { //直接拿到这个目录下的 data ,data里面包括 name,number,id
this.view.rander(this.model.data)
})
},
bindEvents(){ //对view的事件进行绑定
//通过事件委托,监听按钮,实现按钮的功能,如果app里面的点击事件符合add1,就直接执行下面的代码
$(this.view.el).on('click', '#add1',this.addOne.bind(this)) // 加 1 本
$(this.view.el).on('click', 'remove1',this.removeOne.bind(this)) //减 1 本
$(this.view.el).on('click','#reset',this.reset.bind(this)) //归 0
},
addOne(){
var oldNumber = $('#number').text() //String类型
var newNumber = oldNumber - 0 + 1 // -0 是让它变为number类型
this.model.update({number:newNumber}).then(()=>{this.view.render(this.model.data)}) //发送put请求,成功后再去修改数据
},
removeOne(){
var oldNumber = $('#number').text()
var newNumber = oldNumber - 0 - 1
if (newNumber < 0) {
newNumber = 0
}
this.model.update({number:newNumber}).then(()=>{this.view.render(this.model.data)})
},
reset(){
this.model.update({number:0}).then(()=>{this.view.render(this.model.data)})
}
}
controller.init({view:view,model:model}) //用init初始化一下
//模拟假的数据,不用管
function fakeData(){
let book = { //变量,作为缓存,这里原始值,不能每次都去声明这个变量,所以放在最外面
'name': 'JavaScript高级程序设计',
'number': 2,
'id':1
}
//这个api是指在真正返回 response 之前先执行后面的东西,这里就是先执行这个函数
axios.interceptors.response.use(function (response) {
// let config = response.config //获取url里面的书名
// let { url, method, data } = config //这里的data是请求时候的data,response的data是响应时候的data
let {config:{url,method,data}} = response.config //上面两行等于这行
if (url === '/books/1' && method === 'get') { //与node那里很像
response.data = book
}else if(url === "/books/1" && method === "put"){
data = JSON.parse(data) //这里的data是字符串,要用JSON.parse转换成数据的
Object.assign(book,data) //这个api可以实现部分赋值,也可以理解为部分更新,把data的数据传到book里
response.data = book
//这里面的number是动态的,是请求中的data里面的number,但下次得到的又是新的,所以需要一个变量来缓存一下
return response
})
}