【前端】Javascript MVC模式之我见
什么是MVC?
MVC是一种设计模式,即MODEL(模型)、VIEW(视图)、CONTROLLER(控制器)。
MVC模式让每一层做好一件事情,层与层之间保持松耦合,让代码更具可维护性。
问题:
如何划分MVC?
如何命名空间?在团队开发中,有可能会有命名冲突。
所以我们需要在window里面建立java中类似工程的东西,工程下面又有各个子项目
要实现:
简单方式实现对各子项目的MVC各模块装,取功能
实验1:
首先,我希望我的工程依托于我的工具
(function() {
var Util = function() {};
Util.prototype = {
constructor : Util,
// 创建工程和项目
project : function(project, page) {
this[project] = {}; // 工程
this[project][page] = {}; // 子项目
},
}
$$ = new Util();
}) ();
$$.project("VideoPlayer", "video");
console.log(window);
运行结果:
这样的结果是我们希望的。在VideoPlayer工程下有video项目
实验2:
除video外我还想建立一个Student,再调用这个函数会覆盖video,,所以 必须加判断!
将project方法中建立项目、工程代码改为如下:
if (this[project] == undefined) {
this[project] = {};
}
if (this[project][page] == undefined) {
this[project][page] = {}
}
这个时候就可以存在两个子项目了,这两个独立的项目应该有相同的内容
$$.project("VideoPlayer", "video");
$$.project("VideoPlayer", "student");
console.log(window);
运行:
实验3:
继续,当然我的每一个子项目都要包含MVC三个模块,所以,我需要在我每个子工程下建立三个类,所以代码更新至如下
(function() {
var Util = function() {};
var Mvc = function() {
this.model = {};
this.view = {};
this.control = {};
};
Util.prototype = {
constructor : Util,
// 创建工程,创建项目
project : function(project, page) {
if (this[project] == undefined) {
this[project] = {};
}
if (this[project][page] == undefined) {
this[project][page] = new Mvc;
}
},
};
$$ = new Util();
}) ();
$$.project("VideoPlayer", "video");
$$.project("VideoPlayer", "student");
console.log(window);
结果如下:
实验4:
目前咱们只搭了个台子,往后还要给他们(MVC)加东西,因此,还需要装和取两种操作
在model里想加学生信息,而且要方便我以后取,因此要在model里加方法
当然,在实际使用这个工具的时候,咱们肯定是要在持续建类,为了方便建立,我们当然要能时刻定位当下目录
此时工具中还应给出在MVC各模块下增加类的方法
(function() {
var Util = function() {
this.prt = Util.prototype;
};
var Mvc = function() {
this.model = {};
this.view = {};
this.control = {};
};
Util.prototype = {
constructor : Util,
currentPage : this, //定位操作
// 创建工程,创建项目
project : function(project, page) {
if (this[project] == undefined) {
this[project] = {};
}
if (this[project][page] == undefined) {
this[project][page] = new Mvc;
}
this.prt.currentPage = this[project][page];
//定位到当下目录
//为什么不用this,对于左值,会先在当前对象成员里找,找不到则立刻建立
// currenPage的作用,通过它可以知道当前处理的位置,相当于目录转换,类似与java包
},
model : function(className, Klass) {
this.prt.currentPage.model[className] = Klass;
var klass = this.prt.currentPage.model[className];
klass.obj = {};
// 建立对象
},
};
$$ = new Util();
}) ();
$$.project("VideoPlayer", "video");
$$.project("VideoPlayer", "student");
$$.model("StudentModel", function() {
this.name = '';
this.sex = true;
});
console.log(window);
运行结果:
看,每个项目其原型空间中(prototype)都存在prt,他表示目前正在处理的位置,相当于目录转换,和java包异曲同工
实验5:
建立是有了,可取呢?
如果model函数中只传来一个参数,那我们就要执行取操作
有没有发现,这样越来越像Java了,可不可以在建立工程的时候把参数定成XXXX.XXXX.XXXX的形式,建立model的时候参数也定作这样,在工具中我们只用处理传来的字符串,建立工程和类
这样不就形成了java包的模式了
model : function (className, Klass) {
if (arguments.length == 1) {
var index = className.indexOf(".");
if (index == -1) {
return this.prt.currentPage.model[className];
}
var objName = className.substring(index+1);
className = className.substring(0, index);
return this.prt.currentPage.model[className][objName];
}
if (Klass instanceof Function) {
this.prt.currentPage.model[className] = Klass;
return Klass;
}
var classNames = className.split(".");
className = classNames[0];
var objName = classNames[1];
this.prt.currentPage.model[className][objName] = Klass;
},
咱们只看model函数,当参数长度为1时,model用来获取model对象,若长度大于1,当然通过字符串路径添加model类了。
所有代码:
(function () {
var Util = function () {
this.prt = Util.prototype;
};
var Mvc = function () {
this.model = {};
this.view = {};
this.action = {};
};
Util.prototype = {
constructor : Util,
currentPage : this,
package : function (packageName) {
var current = this;
var packages = packageName.split(".");
for (var index in packages) {
var page = packages[index];
if (current[page] == undefined) {
current[page] = {};
}
current = current[page];
}
Mvc.call(current);
this.prt.currentPage = current;
},
model : function (className, Klass) {
if (arguments.length == 1) {
var index = className.indexOf(".");
if (index == -1) {
return this.prt.currentPage.model[className];
}
var objName = className.substring(index+1);
className = className.substring(0, index);
return this.prt.currentPage.model[className][objName];
}
if (Klass instanceof Function) {
this.prt.currentPage.model[className] = Klass;
return Klass;
}
var classNames = className.split(".");
className = classNames[0];
var objName = classNames[1];
this.prt.currentPage.model[className][objName] = Klass;
},
};
$$ = new Util();
}) ();
$$.package("com.mec.video.core");
$$.package("com.mec.student");
$$.model("StudentModel", function (name, sex) {
this.name = name;
this.sex = sex;
});
var StudentModel = $$.model("StudentModel");
$$.model("StudentModel.student", new StudentModel("张三", true));
console.log(window);
运行结果:
总结:
这样运用,把js尽量往java上靠
看上图$$下有我们的整个工程,里面有包名称,包内有MVC,model里放所有类及其对象
对于view层,可以开始将html中带id的element拿出来形成键值对,装入view,不用每次查找再getElementById了(但对于一些后来添加的或更改的就必须要刷新view了,可以在get找不到标签的时候再刷新)
这样就构建了一个简单的前端MVC框架。
根据学习笔记,写出了这篇博文。若有问题,欢迎指教!