「每日一題」MVC 是什麼?(續1)
前後端分離
前端 MVC 就要從前後端分離講起了。
前後端分離是指
一個頁面分為兩部分,瀏覽器上面的工作交給前端做,伺服器上面的工作交給後端做(人員分離)
頁面開發流程是這樣的
1. 瀏覽器第一次載入的頁面只是一個佔位符,比如這樣
<body>n <div id=app></div>n</body>n
2. 前端將其他 HTML 和從伺服器獲取的數據填到佔位符里
偽代碼:nn$.get(/user/1).then(function(user){nn template = (n <h1>{{ name }}</h1>n )nn content = template.replace({{ title }}, user.name)nn $app.html(content)nn})n
3. 用戶提交數據時,前端用 AJAX 提交非同步請求
$form.on(submit, function(){n $.post(/user/1, $form.serialize()).then(function(){n alert(提交成功)n })n})n
老司機的總結
前端老司機發現自己每個項目都要重複上面的流程,於是也想總結一下,歸納一下,抽象一下。
假設我們要做一個用戶中心頁面。
Model - 封裝數據操作
對用戶的增刪改成其實都是非同步請求,我能不能封裝到一起呢?
var userModel = {n find: function(id){n return $.get(/user/+id).then(function(user){n $.extend(userModel, user)n })n },n save: function(id, data){n return $.post(/user/+id, data)n }n}n
出了這些,還有用戶數據的校驗
userModel.validate = function(){n if(this.name === ) return falsen if(this.password === ) return falsen return truen}n
這樣一來,數據相關的操作就都放到這個 model 上了。
View - 視圖渲染
前端的視圖也是 HTML,由於 HTML 裡面沒有數據,所以我們一般都要將數據與 HTML 混合起來。
上面代碼是這樣做混合的:
content = template.replace({{ title }}, user.name)n
顯然這樣的方案功能不夠強大,於是前端們用正則寫出很多強大的模板引擎,如 Handlebars.js、React,最終實現的效果大致是:
content = templateEngine( template, user )n
content 就是帶有數據的 HTML 了。
Controller - 控制器主要是打雜的
還有哪些事情沒做,都交給 Controller 吧:
- 將 content 塞到頁面里
- 瀏覽器事件監聽 - 用戶點擊視圖後去更新數據(如 user)
- 數據事件監聽 - user 數據更新後去更新視圖
對應的代碼:
controller = {n model: userModel,n element: $app,n template: <h1>{{ name }} </h1>........,n events: {n click button: onButtonClick,n submit form : onSubmitFormn },n modelEvents: {n update: onModelUpdate,n remove: onModelRemoven },n init: function(){n var content = templateEngine(this.template, userModel)n this.element.append($app)n n // 遍歷 events 並綁定對應的方法n // 遍歷 modelEvents 並綁定對應的方法n },n onButtonClick: function(){...},n onSubmitForm: function(){...},n onModelUpdate: function(){...},n onModelRemove: function(){...}n}n
總結一下:
- Controller 監聽 Model 變化,Model 一變,Controller 就會去更新 View。
- Controller 監聽用戶交互,用戶點了提交或修改按鈕,Controller 就要去更新 Model。
注意,一個頁面可以有多個 Controller,每個 Controller 負責一個大 div 即可。
Router - 路由
前端 MVC 有路由嗎?可以有,也可以沒有。
如果只是在每個頁面局部使用 MVC,那麼就不需要路由。
如果整站是一個單頁面,那麼就要處理 URL 的變化了(用 PushState API 或者 URL Hash)。
MVC 裡面最複雜的部分是 Controller,它做了太多機械的、繁瑣的事情,比如綁定事件、更新 DOM、更新數據,這也為前端 MVC 沒落留下了隱患,後面的 MVP、MVVM、FLUX 很好地解決這一問題(同時引入了其他問題)。不過 MVC 的概念,我們還是有必要了解的。
更多前端交流,盡在前端交流5群:152052597
推薦閱讀:
※MVC系列——一個異常消息傳遞引發的思考
※Python編程(b三):Python之MVC
※MVC 模式的原理,它在 Android 中是如何運用的?
※zencart 這個國外商城 CMS 源碼寫得怎樣?
※NodeJS的MVC是如何工作的?