MVC的三个对象
Model(数据模型)
Model用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法,会有一个或多个视图监听此模型。一旦模型的数据发生变化,模型将通知有关的视图。
- 读取数据库数据
- 写入html
//伪代码
Model = {
$.get('/user/1').then(function(user){
template = (
<h1>{{ name }}</h1>
)
// 暂时还不知道要填入的数据是什么,用一个占位符表示
content = template.replace('{{ title }}', user.name)
// 用从数据库获取到的数据替换占位符
$app.html(content)
// 放到页面里
$form.on('submit', function(){
// 用户提交数据
$.post('/user/1', $form.serialize()).then(function(){
// AJAX提交异步请求
alert('提交成功')
})
})
}
View(视图)
视图view是它在屏幕上的表示,描绘的是model的当前状态。当模型的数据发生变化,视图相应地得到刷新自己的机会。
- 处理content,使它与HTML结合
View = {
// 集中处理用户事件
// 渲染HTML模板
// 与Model交互
el: '需要刷新的元素' // 通常使用EventBus作为共有属性继承,来获取页面元素
html: '需要插入元素内的HTML内容'
render: { 渲染html }
}
Controller(控制器)
控制器controller定义用户界面对用户输入的响应方式,起到不同层面间的组织作用,用于控制应用程序的流程,它处理用户的行为和数据model上的改变。
- 监听Model,变化时更新View
- 监听用户交互事件,更新Model
Controller = {
function showUser (userId)
user = UserModel.find(userId) // 从Model获取 user 数据
content = readFile('user.html') // 获取 user.html 内容
response = render(content, user) // 将 user 数据填入 HTML 中
return response // 返回给用户
}
EventBus的作用
- 模块通信:在模块化处理时,各模块互不知道其他模块的存在,不能直接相互获取数据,EventBus的存在就解决了模块之间通信的问题。
- 使用:在EventBus模块里监听它的事件,在想使用的地方引入EventBus来触发。
// 伪代码
EventBus {
constructor{ this._eventbus = $(window) }
// 从引用的库里(如jQuery、Vue)获取到,后期改动引用库比较方便
on(eventName, fn) {
return this._eventBus.on(eventName, fn)
}
trigger(eventName, data) {
}
off(eventName, fn) {
}
}
表驱动编程
表驱动法就是一种编程模式(scheme)——从表里面查找信息而不使用逻辑语句(if 和case)。事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。
应用
- 在稳定的复杂度里绑定多个事件
// 哈希表
events:{
'click #app1': 'a操作',
'click #app2': 'b操作',
'click #app3': 'c操作',
'click #app4': 'd操作',
}
autoBindEvents() { // 通过哈希变自动绑定事件
for ( let key in c.events) {
if ( c.events.hasOwnProperty(key) ) {
const spaceIndex = key.indexOf(' ') // 找到'click #app1'空格的数组下标
const part1 = key.slice(0, spaceIndex) // 通过spaceIndex 分割 'click' 和 '#app1'
const part2 = key.slice(spaceIndex + 1)
const value = c[c.events[key]]
v.el.on(part1, part2, value) // 自动把多个事件绑定在一个元素上
}
}
}
对模块化的理解
- 将具有相同功能的代码封装起来,当代码足够复杂时,可以根据一定规范封装成一个整块并单独放在一个文件里,并暴露出一些接口供其他模块引用。
- 一个模块内部是私有的,模块间不能进行直接通信,需要借助EventBus做桥梁。
- 层级结构清晰明了、可按需加载,能有效避免命名冲突
- 可重复使用,便于维护。