深入学习jquery源码之继承框架的实现

时间:2023-02-23 22:01:04


深入学习jquery源码之继承框架的实现

继承框架的实现

实现自己的extend方法

/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function(){
//initializing是为了解决我们之前说的继承导致原型有多余参数的问题。当我们直接将父类的实例赋值给子类原型时。是会调用一次父类的构造函数的。所以这边会把真正的构造流程放到init函数里面,通过initializing来表示当前是不是处于构造原型阶段,为true的话就不会调用init。
//fnTest用来匹配代码里面有没有使用super关键字。对于一些浏览器`function(){xyz;}`会生成个字符串,并且会把里面的代码弄出来,有的浏览器就不会。`/xyz/.test(function(){xyz;})`为true代表浏览器支持看到函数的内部代码,所以用`/\b_super\b/`来匹配。如果不行,就不管三七二十一。所有的函数都算有super关键字,于是就是个必定匹配的正则。
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

// The base Class implementation (does nothing)
// 超级父类
this.Class = function(){};

// Create a new Class that inherits from this class
// 生成一个类,这个类会具有extend方法用于继续继承下去
Class.extend = function(prop) {
//保留当前类,一般是父类的原型
//this指向父类。初次时指向Class超级父类
var _super = this.prototype;

// Instantiate a base class (but only create the instance,
// don't run the init constructor)
//开关 用来使原型赋值时不调用真正的构成流程
initializing = true;
var prototype = new this();
initializing = false;

// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
//这边其实就是很简单的将prop的属性混入到子类的原型上。如果是函数我们就要做一些特殊处理
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
//通过闭包,返回一个新的操作函数.在外面包一层,这样我们可以做些额外的处理
return function() {
var tmp = this._super;

// Add a new ._super() method that is the same method
// but on the super-class
// 调用一个函数时,会给this注入一个_super方法用来调用父类的同名方法
this._super = _super[name];

// The method only need to be bound temporarily, so we
// remove it when we're done executing
//因为上面的赋值,是的这边的fn里面可以通过_super调用到父类同名方法
var ret = fn.apply(this, arguments);
//离开时 保存现场环境,恢复值。
this._super = tmp;

return ret;
};
})(name, prop[name]) :
prop[name];
}

// 这边是返回的类,其实就是我们返回的子类
function Class() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}

// 赋值原型链,完成继承
Class.prototype = prototype;

// 改变constructor引用
Class.prototype.constructor = Class;

// 为子类也添加extend方法
Class.extend = arguments.callee;

return Class;
};
})();

通过Class的extend方法来初始化ListPager

(function(scope){
var ListPager = Class.extend({
init: function(){},
render: function(){
var _self = this;
//弹出卡片界面的大小[60%,80%]
_self.cardSize = _self.cardSize || ['80%','80%'];
//弹出卡片界面方式:页面层(这里content是一个普通的String):1;iframe层(content是一个URl):2
_self.cardPopStyle = _self.cardPopStyle || LayuiPopStyle.LAYUI_IFRAME_LAYER;
_self.tableId = _self.container + "." + _self.primaryKey;
//plugins 这个可以不传,但是请不要传空数组过来
var plugins = _self.plugins || ['table','form'];
var p = _self.assemblyFormPrams();
//利用layui 绘制列表 ( url : _self.url+"?decAjaxReq=yes", 给ajax请求加密)
layui.use(plugins, function(){
var option = $.extend({elem: "#" + _self.container,
url : _self.url,
cols: _self.title,
method: RequestMethod.METHOD_POST,
id : _self.tableId,
even: true,
page: true, //是否显示分页
pageNum: 1,
limit: _self.pageSize, //每页默认显示的数量
limits:[5,10,15,20,30]}, _self.layOption);
//展示已知数据
layui.table.render(option);

//渲染部分layui组件
_self.initLayuiPlugin();

//监听工具条
layui.table.on('tool(' + _self.container + ')', function(obj){ //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
if(_self.hookMethod && $.isFunction(_self.hookMethod)){
_self.hookMethod(obj); //回调 子类中的 钩子方法
}
});
//复选框事件选中以后回调
layui.table.on('checkbox(' + _self.container + ')', function(obj){
if(_self.tableAfterChecked && $.isFunction(_self.tableAfterChecked)){
_self.tableAfterChecked(obj); //回调 子类中的 钩子方法
}
});
});
//界面绘制完成, 初始化界面事件
_self.initEvent();
},
initLayuiPlugin: function(){
var _self = this;
},
initEvent: function(){
var _self = this;
//列表 增删改查
$("div[name='listBtns'] button").unbind('click').bind('click', function(){
var action = "_self." + $(this).attr("action");
eval(action);
});

//列表查询、重置
$("div button[type='button']",$("#" + _self.container + "-QueryForm"))
.unbind('click')
.bind('click', function(){
var action = "_self." + $(this).attr("action");
eval(action);
});
},
assemblyFormPrams: function(){ //组装列表模糊查询表单数据
var _self = this;
var formParam = $("#" + _self.container + "-QueryForm").serializeArray(),
reqParam = {};
for(var o in formParam){
if(formParam[o]["name"]){
reqParam[formParam[o]["name"]] = formParam[o]["value"];
}
}
return reqParam;
},
listQuery: function(){
var _self = this;
layui.table.reload(_self.tableId, {
where: _self.assemblyFormPrams()
});
},
/**
* 获取选中的数据
*/
getSelectRows: function(){
var checkStatus = layui.table.checkStatus(this.tableId);
return checkStatus.data;
},
getSelectIds: function(){
var data = this.getSelectRows();
var ids = [];
if($.isEmptyArray(data))
return ids;
for(var i = 0; i < data.length; i++){
ids.push(data[i][this.primaryKey]);
}
return ids;
},
view: function(curDom, event){
var _self = this;
var data = _self.getSelectRows();
if (data.length != 1) {
layer.msg("请选中一条数据进行查看");
return;
}
var url = $(curDom).attr("url") + "?act=" + WebConst.READ + "&entityId=" + data[0][_self.primaryKey];
var title = $(curDom).attr("title");
var layIndex = layer.open({
type: this.cardPopStyle,
title: title,
maxmin: true,
shadeClose: true, //开启遮罩关闭
area : this.cardSize,
content: this.cardPopStyle == LayuiPopStyle.LAYUI_CONTENT_LAYER ? $.loadHtml(url) : url,
success: function(layero){
layero = _self.cardPopStyle == LayuiPopStyle.LAYUI_CONTENT_LAYER ? layero : layer.getChildFrame('body', layIndex);
if(_self.cardPopStyle == LayuiPopStyle.LAYUI_CONTENT_LAYER){
layero.setValues(data[0]);
}
layui.form.render();
}
});
},
add: function(curDom, event){
var _self = this;

//新增之前回调函数
if(_self.beforeAdd && $.isFunction(_self.beforeAdd)){
_self.beforeAdd();
}

var url = $(curDom).attr("url") + "?act=" + WebConst.ADD;
var title = $(curDom).attr("title");
layer.open({
type: this.cardPopStyle,
title: title,
area: this.cardSize,
maxmin: true,
shadeClose: false, //开启遮罩关闭
content: this.cardPopStyle == LayuiPopStyle.LAYUI_CONTENT_LAYER ? $.loadHtml(url) : url,
success : function(layero){
layui.form.render();
},
end: function(){ //销毁列表回调方法
layui.table.reload(_self.tableId)
if(_self.closeCard && $.isFunction(_self.closeCard)){
return _self.closeCard();
}
return false;
},
cancel: function(){

}
});
},
edit: function(curDom, event){
var _self = this;
var data = _self.getSelectRows();
if (data.length != 1) {
layer.msg("请选中一条数据进行修改");
return;
}

//修改之前回调函数
if(_self.beforeUpd && $.isFunction(_self.beforeUpd)){
_self.beforeUpd();
}

var url = $(curDom).attr("url") + "?act=" + WebConst.EDIT + "&entityId=" + data[0][_self.primaryKey];
var title = $(curDom).attr("title");
var layIndex = layer.open({
type: this.cardPopStyle,
title: title,
maxmin: true,
shadeClose: false, //开启遮罩关闭
area : this.cardSize,
content: this.cardPopStyle == LayuiPopStyle.LAYUI_CONTENT_LAYER ? $.loadHtml(url) : url,
success: function(layero){
layero = _self.cardPopStyle == LayuiPopStyle.LAYUI_CONTENT_LAYER ? layero : layer.getChildFrame('body', layIndex);
if(_self.cardPopStyle == LayuiPopStyle.LAYUI_CONTENT_LAYER){
layero.setValues(data[0]);
layui.form.render();
}
},
end: function(){ //销毁列表回调方法
layui.table.reload(_self.tableId)
if(_self.closeCard && $.isFunction(_self.closeCard)){
return _self.closeCard();
}
return false;
},
cancel: function(){ //点击左上角关闭按钮回调方法
if(_self.cardPopStyle == LayuiPopStyle.LAYUI_IFRAME_LAYER){ //从列表调用卡片页面数据
var frameId = document.getElementById('layui-layer' + layIndex).getElementsByTagName("iframe")[0].id,
closeCallback = $('#'+frameId)[0].contentWindow.beforeClose;
if(closeCallback && $.isFunction(closeCallback)){
return closeCallback();
}
}
}

});
},
del: function(curDom, event){
var _self = this;
var data = _self.getSelectIds();
if(data.length == 0){
layer.msg("请至少选择一条需要删除的数据");
return;
}
var url = $(curDom).attr("url") + "?act=" + WebConst.DELETE;
layer.confirm('确定删除吗', function(index){
layer.close(index);
$.ajaxReq(url,$.toJSON(data),function(){
layui.table.reload(_self.tableId)
});
});
}
});
scope.ListPager = ListPager;
})(window);

通过extend实现继承,获取ListPager的中方法,并调用

ShowPipeList = ListPager.extend({

init : function(container, primaryKey, url){
//列表容器
this.container = container;
//主键字段
this.primaryKey = primaryKey;
//数据请求地址
this.url = url;
//界面需要引用的插件
this.plugins = ['table', 'element', 'form', 'laydate', 'layer','carousel'];
// //弹出卡片界面的大小[60%,80%]
// this.cardSize = ['100%','100%'];
// //弹出卡片界面方式:页面层(这里content是一个普通的String):1;iframe层(content是一个URl):2
this.cardPopStyle = 2;
//每页大小
this.pageSize = 5;
//列表头
this.title = [[

{field: 'startTime', title: '开始时间', width: 160},

{field: 'endTime', title: '结束时间', width: 160},


]];
//插件是基于layui封装的, layOption是对layui的参数扩展(具体api参照layui属性)
this.layOption = {

};
},
initLayuiPlugin: function(){
this._super();

var table = layui.table;
var laydate = layui.laydate;
//时间选择器
laydate.render({
elem: '#test5'
,type: 'time'
,theme: '#050a3c'
});

laydate.render({
elem: '#test6'
,type: 'time'
,theme: '#050a3c'
});
},
initEvent: function(){
this._super();
//TODO 父类仅仅绑定了工具条通用按钮事件, 如有其他事件请在这里定义
},
hookMethod:function(obj){

var data = obj.data,
url = CONTEXT_PATH + '/cusviews/pipe/listPipePoint';
var param = {
cobwebId : data.cobwebId
}
var retData = $.getData(url,param);
}
});
$(function(){
var url = CONTEXT_PATH + '/cusviews/pipe/listPipe';
var showPipeList = new ShowPipeList("pipeList", "cobwebId", url);
showPipeList.render();
$(".tc_box .cbar").scrollBar();
})

继承实现的过程

 

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现

深入学习jquery源码之继承框架的实现