[JavaScript]MVC淺析
MVC淺析
MVC或多或少都有聽說過,我知道如果要作為一個前端的話,MVC應該是一個顯示技術水平的檻,是繞不過去的,所以我乖乖來寫這篇文章,對MVC進行一些粗淺的分析和歸納,以加深對MVC的理解。
MVC是一種代碼組織形式,他把代碼依據功能的不同劃分成三個部分,分別是Model、Controller、View。
View代表視圖,Model代表對數據的操作(存儲和獲取等),Controller代表了View和Model兩者之間的交互邏輯以及其他。
他們之間的相互作用是這樣的:用戶對View視圖做出了操作,監聽著View視圖的controller接收到了View的變化通知,然後按需求去調用Model,Model向server發出請求;server返回響應給Model,Model返回數據給Controller,Controller根據接收到的數據更新View視圖。
用一張圖來表示就是:
接下來改寫一下之前使用leanCloud添加數據庫創建留言功能的代碼:
//message.js !function(){ // 初始化 var APP_ID = ‘xxxxxxxxxxxxxxxxxxxxxxxxxx‘; var APP_KEY = ‘xxxxxxxxxxxxxxxxxxxxxx‘; AV.init({ appId: APP_ID, appKey: APP_KEY }); // 拉取歷史留言 var query = new AV.Query(‘Message‘); query.find().then(function (messages) { messages.forEach(function (item) { let li = $(‘<li></li>‘).text(item.attributes.name +‘:‘+item.attributes.content) $(‘#comments‘).append(li) }); }).then(function (messages) { // 更新成功 }, function (error) { // 異常處理 }); let myForm = document.querySelector(‘#postMessage‘) // 為什麽要監聽表單的submit事件而不是button的click事件,因為一旦用戶輸完密碼按回車鍵提交的話,監聽就落空了.submit事件包括了點擊和回車 myForm.addEventListener(‘submit‘,function(e){ // 阻止傳播,防止點擊刷新 e.preventDefault() //獲取輸入框內的值 let content = $(‘input[name="content"]‘).val() let name = $(‘input[name="name"]‘).val() var Message = AV.Object.extend(‘Message‘); var messages = new Message(); messages.save({ "name":name, "content":content , }).then(function(object) { let li = $(‘<li></li>‘).text(object.attributes.name +‘:‘+ object.attributes.content) $(‘#comments‘).append(li) myForm.querySelector(‘input[name="content"]‘).value = ‘‘ }) }) }.call()
View
View代表視圖,因為我們只對這個提交表單和展示列表進行操作,所以View就是:
var view = $(‘section.messages‘)
Model
Model代表對數據的操作(存儲和獲取等)。
所以Model應該只負責保存提交上來的留言到leanCloud,和從leanCloud獲取留言以及數據庫初始化的工作(給服務器發送請求,接收服務器響應),返回數據給Controller:
var model = { // 初始化 init : function(){ var APP_ID = ‘xxxxxxxxxxxxxxxxx‘ var APP_KEY = ‘xxxxxxxxxxxxxxxxxxxxxxxx‘ AV.init({appId: APP_ID,appKey: APP_KEY}) }, //獲取數據 fetch:function(){ var query = new AV.Query(‘Message‘); return query.find() //Promise對象 }, // 保存數據 save:function(name,content){ var Message = AV.Object.extend(‘Message‘) var messages = new Message(); return messages.save({ "name":name, "content":content , }) }, }
Controller
Controller代表了View和Model兩者之間的交互邏輯以及其他。
所以,他會負責監聽View的事件通知,對Model的調用;從Model獲取返回數據,更新View視圖。
var controller = {
view : null,
model: null,
init : function(view,model){
this.model = model
this.view = view
this.myForm = document.querySelector(‘#postMessage‘)
this.model.init()
this.loadMessages()
this.bindEvents()
},
//加載留言數據
loadMessages : function () {
this.model.fetch().then((messages) => {
messages.forEach((item) => {
let span = $(‘<span></span>‘).text(‘發布於:‘+ this.parseTime(item.createdAt))[0]
let li = $(‘<li></li>‘).text(item.attributes.name + ‘:‘ + item.attributes.content)
li.append(span)
$(‘#comments‘).append(li)
});
}).then(function (messages) {
// 更新成功
}, function (error) {
// 異常處理
});
},
bindEvents : function(){
this.myForm.addEventListener(‘submit‘,(e) => {
// 阻止傳播,防止點擊刷新
e.preventDefault()
this.saveMessages()
})
},
saveMessages : function(){
//保存數據
//獲取輸入框內的值
let content = $(‘input[name="content"]‘).val()
let name = $(‘input[name="name"]‘).val()
this.model.save(name,content).then((object) => {
let span = $(‘<span></span>‘).text(‘發布於:‘+ this.parseTime(object.createdAt))[0]
let li = $(‘<li></li>‘).text(object.attributes.name +‘:‘+ object.attributes.content)
li.append(span)
$(‘#comments‘).append(li)
document.querySelector(‘#postMessage input[name="content‘).value = ‘‘
},function(error){
console.log(error)
})
},
parseTime:function(d){
const newDate = d.getFullYear() + ‘-‘ + (d.getMonth() + 1) + ‘-‘ + d.getDate() + ‘ ‘
+ d.getHours() + ‘:‘ + d.getMinutes() + ‘:‘ + d.getSeconds();
return newDate;
}
}
controller.init(view,model)
整體MVC
!function(){
var view = $(‘section.messages‘)
var model = {
init : function(){
var APP_ID = ‘xxxxxxxxxxxxxxxxxxxxxxx‘
var APP_KEY = ‘xxxxxxxxxxxxxxxxxxxxxxxxxx‘
AV.init({appId: APP_ID,appKey: APP_KEY})
},
//獲取數據
fetch:function(){
var query = new AV.Query(‘Message‘);
return query.find() //Promise對象
},
// 保存數據
save:function(name,content){
var Message = AV.Object.extend(‘Message‘)
var messages = new Message();
return messages.save({
"name":name,
"content":content ,
})
},
}
var controller = {
view : null,
model: null,
init : function(view,model){
this.model = model
this.view = view
this.myForm = document.querySelector(‘#postMessage‘)
this.model.init()
this.loadMessages()
this.bindEvents()
},
loadMessages : function () {
this.model.fetch().then((messages) => {
messages.forEach((item) => {
let span = $(‘<span></span>‘).text(‘發布於:‘+ this.parseTime(item.createdAt))[0]
let li = $(‘<li></li>‘).text(item.attributes.name + ‘:‘ + item.attributes.content)
li.append(span)
$(‘#comments‘).append(li)
});
}).then(function (messages) {
// 更新成功
}, function (error) {
// 異常處理
});
},
bindEvents : function(){
this.myForm.addEventListener(‘submit‘,(e) => {
// 阻止傳播,防止點擊刷新
e.preventDefault()
this.saveMessages()
})
},
saveMessages : function(){
//獲取輸入框內的值
let content = $(‘input[name="content"]‘).val()
let name = $(‘input[name="name"]‘).val()
this.model.save(name,content).then((object) => {
let span = $(‘<span></span>‘).text(‘發布於:‘+ this.parseTime(object.createdAt))[0]
let li = $(‘<li></li>‘).text(object.attributes.name +‘:‘+ object.attributes.content)
li.append(span)
$(‘#comments‘).append(li)
document.querySelector(‘#postMessage input[name="content‘).value = ‘‘
},function(error){
console.log(error)
})
},
parseTime:function(d){
const newDate = d.getFullYear() + ‘-‘ + (d.getMonth() + 1) + ‘-‘ + d.getDate() + ‘ ‘
+ d.getHours() + ‘:‘ + d.getMinutes() + ‘:‘ + d.getSeconds();
return newDate;
}
}
controller.init(view,model)
}.call()
MVC只能使用Controller通過Model操作自身的View,功能劃分合理,所以對其他的文件和View來說是解耦的。利於維護和編寫。
註意事項
Controller中this的使用,箭頭函數不會改變this的指向。
[JavaScript]MVC淺析