MVC
Model 和服务器交互,Model 将得到的数据交给 Controller,Controller 把数据填入 View,并监听 View
用户操作 View,如点击按钮,Controller 就会接受到点击事件,Controller 这时会去调用 Model,Model 会与服务器交互,得到数据后返回给 Controller,Controller 得到数据就去更新 View
MVC中的Model.js(数据模型,初始化、获取、保存数据)
window.Model = function (options) {
let resourceName = options.className//options就是{className:'leaveMessage'},所以options.className也就是'leaveMessage'
return {
initAV: function () {
var APP_ID = 'psn8GPYgDquNCPxAS9BShJuI-gzGzoHsz'
var APP_KEY = '67xohX3oz0Ft1f06lfm6k6ii'
AV.init({ appId: APP_ID, appKey: APP_KEY })
},
fetch: function () {
var query = new AV.Query(resourceName);
return query.find()
},
save: function (obj) {
var LeaveMessage = AV.Object.extend(resourceName)//创建leaveMessage表
var leaveMessage = new LeaveMessage()
return leaveMessage.save(obj)
}
}
}
MVC中的View.js(用户界面)
window.View = function(selector){
return document.querySelector(selector)
}
MVC中的Controller.js(控制器接受用户的输入并调用模型和视图去完成用户的需求。)
window.Controller=function(options){
var init = options.init//这个init是保存每个功能自己独特的属性
let object = {
view:null,
model:null,
init:function(view,model){//这个init保存公共的属性
this.view = view
this.model = model
this.model.initAV()
init.call(this,view,model)
//以object为this,在调用options的init(),所以options的init()中的this都会被指定为object。
//但是options的init中的属性都是options的,object并没有,所以需要一个for循环,将options中的属性指定给object,以便调用。for循环见下方代码
//this是object,init是options.init,将此处的this指向options的init中的this,所以options的init中的this就是object。
// 将options.init中的内容调用到这里,这样就都合并在一起了
this.bindEvents()
}
}
for(let key in options){
if(options[key]!==init){
object[key]=options[key]
}
}
return object
}
具体实现:leaveMessage.js
!function () {
var model = Model({className:'leaveMessage'})//MVC中的M,存放数据,展示数据有哪些操作,初始化、获取、保存
var view = View('section.message')//MVC中的V,说明在页面的哪个部分
var controller = Controller({//小c是大C的实例
messageList: null,
postMessageForm: null,
init: function (view, model) {
//这里的this被指定为Controller.js中的init.call(this,view,model)中的this,也就是object
//但是Controller中的object没有messageList、postMessageForm、loadMessages这些属性,但是options有
//所以需要在Controller中添加for...in循环,将options中的属性指定给object,除了init属性,因为object已经有了该属性
this.messageList = view.querySelector('#messageList')
this.postMessageForm = view.querySelector('#postMessageForm')
console.log(this)
this.loadMessages()
},
loadMessages: function () {
//批量获取数据
this.model.fetch().then(
(messages) => {
var array = messages.map((value) => value.attributes)//es6写法`${array[i].name}:${array[i].content}`
// array.forEach(value => {
// var li = document.createElement('li')
// li.innerText = `${value.name}:${value.content}`
// this.messageList.appendChild(li)
// });
//使dom一次性插入文档。而不是每遍历一次插入一次
var htmlTemp = document.createElement('ol');
for (var i = 0; i < array.length; i++) {
htmlTemp.innerHTML += '<li>' + `${array[i].name}:${array[i].content}` + '</li>';
}
this.messageList.append(htmlTemp)
},
function (error) {
})
.then(
function () { console.log('无异常') },
function (error) {
console.log(123413421423432423413123)
console.log(error)
})
},
bindEvents: function () {
//上传数据
this.postMessageForm.addEventListener('submit', (e) => {
e.preventDefault()
this.saveMessages()
})
},
saveMessages: function () {
var contentInClass = this.postMessageForm.querySelector('input[name=content]').value
var nameInClass = this.postMessageForm.querySelector('input[name=name]').value
this.model.save({name:nameInClass, content:contentInClass}).then((object) => {
// window.location.reload()//页面自动刷新
var li = document.createElement('li')
li.innerText = `${object.attributes.name}:${object.attributes.content}`
this.messageList.querySelector('ol').appendChild(li)
console.log(`content获取到了${contentInClass}`)
this.postMessageForm.querySelector('input[name=content]').value = ''
console.log('存入成功')
}).then(() => { }, function (error) {
console.log(error)
})
}
})
controller.init.call(controller, view, model)
// controller.init(view, model)
}.call()