什么是MVC?
在我的理解里,mvc是一种编写代码的方式。符合了代码分块的思想。使用mvc+面向对象的思想,可以简化代码,分块处理代码。
Model 操作数据
View 表示视图
Controller 是控制器
Model 和服务器交互,Model 将得到的数据交给 Controller,Controller 把数据填入 View,并监听 View
用户操作 View,如点击按钮,Controller 就会接受到点击事件,Controller 这时会去调用 Model,Model 会与服务器交互,得到数据后返回给 Controller,Controller 得到数据就去更新 View。
具体操作如下图
![(2Z5QP2KSICKEBZ_LAROMU.png
下面演示以面向对象的思想进行的MVC操作
1.MVC的View操作
view主要是用来操作用户看的到的视图的,所以View的主要工作就是,获取选择器,由于每一个js文件肯定都要操作这个View,那么可以把View封装成一个类,代码如下
window.View = function(selector){
return document.querySelector(selector)
//因为view大家都要调用的所以要把它设置成一个全局对象
}
调用方法:var view = Window.View('#selector') //window 是全局变量可以省略
var view = View('#selector')
2.MVC的Model操作
Model主要是对使用到的数据进行处理,主要有3种方法,init,fetch ,save 方法
具体使用方法如下
var model = {
initAV: function () {},
fetch:function(){},
save:function(){}
}
把它封装成一个对象
window.Model = function(options){
let resourceName = options.resourceName
//注意这个是返回值
return{
initAV:function(){
var APP_ID = 'YHRYNXumFCQUTukhjJ7U8cRL-gzGzoHsz';
var APP_KEY = 'LAtLqqlwFjlBnnsRGnEEGtQa';
AV.init({ appId: APP_ID, appKey: APP_KEY });
},
fetch:function(){
这里作为一个类,Message是传入的变量,要在函数开始时确定,这里就 使用到了闭包的知识,Message是这个函数之外的变量
// var query = new AV.Query('Messsage');
var query = new AV.Query(resourceName);
return query.find()
},
save:function(object){
//以封住前的方法为例子,这个方法要传入两个变量,name和content
//把他封装成一个对象object{'name':name,'content':content}
var Messsage = AV.Object.extend(resourceName);
var messsage = new Messsage();
return messsage.save(object)
}
// save:function(name,content){
// var Messsage = AV.Object.extend('Messsage');
// var messsage = new Messsage();
// return messsage.save({
// 'name': name,
// 'content': content
// })
// }
}
}
使用方法:
var model = Model({resourceName:'Messsage'})
调用这个类的时候就会调用它的三个方法
model.init()
model.fetch()
model.save({'name':name,'content':content})
3.MVC的Controller操作
Controller主要是对使用到的数据进行处理,主要有2种方法,init,bindEvents 方法,有几个重要的属性,view和model,用对象的方式封装代码
第一步:我们先要写一个模板,把大家都会有的属性放在这个模板里
window.controller = function(){
return{
view:null,
model:null,
init:function(view,model){
this.view = view
this.model = model
this.model.init()
this.bindEvents()
},
bindEvents:function(){}
}
}
第二步:我们要进行特化,因为我们的要操作的对象的init方法不止有这几个属性,
例如:每个controller特有的方法,我们要做的是就是如果我们初始化这个Controller类的时候(调用Controller类的init方法的时候)
也要调用我们自己写的方法,所以我们要把两个init结合起来
1.我们首先要获取到实例对象的init方法
window.controller = function(option){
let init =option.init
2.调用完模板的init之后,要调用option的init方法。
//这一步的目的是,调用完模板的init之后
//要调用option的init方法。
init.call(this,view,model)
3.注意,这里写错了,这时的this,是函数内的this,所以这个this指的是window。我们要的这个this是option。
所以要把init改成对象。下面还是在修改问题
window.controller = function(option){
let init =option.init
//这里的this不在函数里,所以1这个this其实是window
//我以前以为是window.controller,但是他妈的Controller是我写的一个函数啊
//执行这个函数的还是window啊,所以下面的代码错了啊
//this.bindEvents = option.bindEvents()
let object ={
view:null,
model:null,
init:function(view,model){
this.view = view
this.model = model
this.model.init()
//上面那个改成这样不就没问题了吗
option.init.bindEvents()
//这一步的目的是,调用完模板的init之后
//要调用option的init方法。
init.call(this,view,model)
}
}
return object
}
在自己的类中的代码:
var controller = Controller({
init: function (view,model) {
this.messageList = document.querySelector('#messageList')
this.form = document.querySelector('#postMessageForm')
this.loadMessages()
这个地方因为,模板类中已经对view,model和model.init,也调用了options.bindEvents事件,进行过初始化了,所以不用在自身的init中调用了
},
这里是我们独有的代码
loadMessages:function(){
this.model.fetch().then( (messsage) =>{
let array = messsage.map(item => item.attributes)
//map函数的使用map(item => item的操作)
array.forEach(element => {
let li = document.createElement('li')
li.innerText = `${element.name}:${element.content}`
this.messageList.appendChild(li)
})
}, function (error) {
})
.then(() => { }, (error) => {
console.log(error)
})
},
bindEvents:function(){
this.form.addEventListener('submit', (e)=>{
e.preventDefault()
this.saveMessage()
})
},
saveMessage:function(){
let myform = this.form
let name = myform.querySelector('input[name=name]').value
let content = myform.querySelector('input[name=content]').value
this.model.save({'name':name,'content':content}).then(function (object) {
alert('留言成功')
let li = document.createElement('li')
li.innerText = `${object.attributes.name}:${object.attributes.content}`
this.messageList.appendChild(li)
myform.querySelector('input[name=name]').value = ' '
myform.querySelector('input[name=content]').value = ' '
})
}
})
}
4. 这里还存在一个问题,就是我们执行这个函数的时候。自己写的函数执行不到啊比如loadMessage等,所以这里要遍历这个option把不是init的属性放到模板里面去
for(let key in option){
if (key!=='init') {
object[key] = option[key]
//这里要注意我们要把什么赋值,就把他 放前面
//放后面会有他妈的问题!!!!!!!!!
}
}