JScript快速开发框架 Edk 简介:概述

简介: 自从本日起,开始写写关于 Edk 的文章。要开始理顺思路咯~彻彻底底弄好 Edk!    说明:    一、尽管框架这玩意不好做,用现成的库方便,但在编写框架时,还是可以学到许多一般应用无法学到的知识。

自从本日起,开始写写关于 Edk 的文章。要开始理顺思路咯~彻彻底底弄好 Edk!

    说明:
    一、尽管框架这玩意不好做,用现成的库方便,但在编写框架时,还是可以学到许多一般应用无法学到的知识。
    二、本代码可以免费使用、修改,希望我的程序能为您的工作带来方便,同时请保留这份请息。
    三、在其他优秀库的面前,edk.js算很简单的东西,其实基本上都谈不上什么原创之类的。

对象的类型

/**
 * 检查对象的类型。支持 null/undefined/String/Array/Nubmer/Boolean/Date/RegExp。
 * 推荐 Winter 文章:http://www.cnblogs.com/winter-cn/archive/2009/12/07/1618281.html
 * @param	{Any}		foo 要被检查类型的对象。
 * @return	{Funciton}
 */
$.type = function(foo){
	if (foo === null) {
		return 'null';
	}else if(typeof foo == 'undefined'){
		return 'undefined';
	}
	// constructor 判断比 instanceof 更精确,因为 instanceof 对父类亦有效。
	switch (foo.constructor){
		case Boolean :
			return Boolean;
		case Number :
			return Number;
		case String :
			return String;
		case Array :
			return Array;
		case Date :
			return Date;
		case RegExp :
			return RegExp;
	}

	if(foo instanceof Boolean){
		return Number;
	}else if(foo instanceof Number){
		return Number;
	}else if(foo instanceof String){
		return String;
	}else if(foo instanceof Array){
		return Array;
	}else if(foo instanceof Date){
		return Date;
	}else if(foo instanceof RegExp){
		return RegExp;
	}
	
	switch (typeof foo){
		case 'undefined' :
		case 'unknown' :
		case 'function' :
		case 'regexp' :
			return 'null';
		case 'boolean' :
		case 'number' :
			return Number;
		case 'date' :
			return Date;
		case 'string' :
			return String;
		case 'object' :
			return Object;
		case 'array' :
			return Array;
	}
	
	return null; // 什么类型都判断不了……
}

对象的原语

/**
 * 
 * @param  {Mixed} v
 * @return {Mixed}
 */
$.getPrimitives = function (v){
    switch(v){
    	case 'null':
    		return null;
    	case 'true':
    		return true;
    	case 'false':
    		return false;
    	case String(Number(v)):
    		return Number(v);
    	case (new Date(v)).toString(): // v is a date but in Stirng Type
			return new Date(v);
    }
	return v; // 未转换。
}

明显,这里的 Date 不是原语类型,不应加入到 getPrimitives()中去,但是某些时候恰恰就是需要判定日期类型的,于是得加上。

对象的继承

对象的复制

对象的序列化

客户端信息

封装一下客户端信息:

/**
 * 返回请求的路径(即当前页面的路径)。
 * @return {String} url
 */
function getPath(){
	return Request.ServerVariables('URL')();
}

/**
 * 获取请求的方法。
 * @return {String}
 */
function getHTTP_Method(){
	return Request.ServerVariables('HTTP_METHOD')();
}


/**
 * @return {String/Null}
 */
function getReferer(){
	var arr = Request.ServerVariables('all_raw')().match(/referer:\s*(.*)/i);
	return arr == null ? null : arr[0];
}
处理响应:

/**
 * 统一编码为UTF-8。
 */
function setUTF8(){
	Response.Charset		= "utf-8";
	Session.CodePage		= 65001;
	Session.Timeout			= 200;
	Server.ScriptTimeout	= 100;		
}	

/**
 * 301 永久重定向。
 * @param {String} url 要跳转的地址。
 */
function urlForward(url){
	Response.Status = "301 Moved Permanently";
	Response.addHeader("Location", url);
	Response.End();
}	

/**
 * 强制不缓存。
 */
function noCache(){
	with(Response){
		buffer	= false;
		expires	= -1;
		addHeader("Pragma",		"no-cache");
		addHeader("cache-ctrol","no-cache");
	}	
}

序列化 Request 对象

获取来自表单的各个字段的数据。HTTP FORM 所提交的数据乃是 key/value 配对的结构。本函数是把这些 key/value 集合转化成为 JavaScript 对象。这是 post 包最核心的函数。对各个字段有 decodeURI()、unescape()、$$.getPerm() 自动类型转化的功能。@param {Boolean/String} isAllRequest true 表示为返回 QueryString 和 Form 的 Request 对象集合。如果指定 form 则返回表单的 hash 值,如果指定 QueryString 则返回 URL 上面的参数 hash。

/**
 * @return {Object} 客户端提交的数据或查询参数。
 */
function every(collection){
	var count	= collection.count;
	var obj		= {
		count	: count				// 字段总数
	};
	var emu		= new Enumerator(collection);
	var key, v;
	
	while(count > 0 && !emu.atEnd()){
        key		 = emu.item().toString();
        v		 = collection(key)(); 	// MS ASP这里好奇怪,不加()不能返回字符串
        
        obj[key] = $$.getPrimitives(v);	// 进行自动类型转换。
		
		emu.moveNext();
	}
    
    return obj;
};


this.formPost	 = every.delegate(Request.Form);
this.queryString = every.delegate(Request.QueryString);

getRawPost()

Raw POST 的解析器。Raw POST 也是标准 HTTP POST 方式的一种,但不像 key1=value2&key2=value2 形式提交的文本,而是一堆二进制的数据。浏览器提交的 POST 数据视作原始的数据,须经过 Adodb.Stream 二进制解码后才可以使用。注意:一旦使用过该方法。Request.Form('key') 就无法使用,但通过 URL 传递的 QueryString 仍可用。

/**
 * @return {Object}
 */
function getRawPost(){
    with(new ActiveXObject('Adodb.Stream')){
		open();
		type	 = 2;			// 2 = adTypeText
		writeText(Request.binaryRead(Request.totalBytes));
		position = 0;
		charset  = "us-ascii";	// gb2312?
		position = 2;
		eval('var requestObj = ' + readText());// 使用 eval()函数时,必须要一个变量来承载!
		close();
		return requestObj;
   }
}

/**
 * 是否POST提交数据。
 * @return {Boolean}
 */
function isPOST(){
    return Request.ServerVariables('HTTP_METHOD')() == "POST";
}

/**
 * 获取 HTTP 报文的 ContentType。可支持 GET 操作下的 ContentType。
 * @return {String}
 */
function getContentType(){
    return Request.ServerVariables('Content_Type')();
}
     
/**
 * 返回是否Raw 的POST。这个方法在某种场合必须使用,例如Ext.Direct。
 * 约定:凡application/json的提交均视作Raw POST。
 * @return {Boolean}
 */
function isRawPOST(){
    return isPOST() && (getContentType().indexOf('application/json')) != -1
}

XML处理

Cross Browser XML Loader:

/**
 * 兼容浏览器与服务端的 XML 加载器。注意,当前模式下关闭了异步的通讯方式。
 * create a document object
 * @param	{String}	xml		XML 文档路径或者 XML 文档片段。
 * @param	{Boolean}	isNode	true 表示为送入的为 XML 文档片段。
 * @return	{Object} the document
 */
function loadXML(xml, isNode){
	var doc;
	
	if(typeof ActiveXObject != 'undefined'){
		doc = $$.xml.doc();
	}else if(typeof document != 'undefined' && !isNode){
		if(document.implementation && document.implementation.createDocument){
			doc = document.implementation.createDocument("", "", null);
		}  
	}else if(typeof DOMParser != 'undefined' && isNode){
		doc = new DOMParser().parseFromString(xml, "text/xml");		// 加载XML片段(Moliza Firefox)
		return doc;
	}
	
	if(!doc){
		throw '创建XML文档对象失败!';
	}
	
	doc.async = false;  // 关闭异步特性
	
	if		(xml && !isNode && (doc.load(xml) 	 == false)){		// 加载一份完整的XML文档(Moliza Firefox 与 IE均如此)
		throw '加载XML文档资源失败!';
	}else if(xml &&  isNode && (doc.loadXML(xml) == false)){		// 加载XML片段(IE)
		throw '加载XML片段失败!';									
	}
	
	return doc;
}
	
/**
 * 定位某一 XML 节点。如果找不到则返回一空数组。
 * 用法:
	var doc = loadXML('edk.xml');
	var xml = getNode.call(doc, '//head', false); 
 * @param	{String}	xpathQuery	查询定位符。
 * @param	{Boolean}	isSerialize	可选的,是否序列号查询结果为字符串,默认为true。
 */
loadXML.getTpl = tpl.getTpl = function(xpathQuery, isSerialize){
	var nodes = [];
	var msg = 'NO Exist Node! 不存在匹配的节点,请检查输入的条件再作查询。';
	
	if(typeof isSerialize == 'undefined'){
		isSerialize = true;
	}
	
	if(typeof this.selectNodes != 'undefined'){
		nodes = this.selectSingleNode(xpathQuery);
		if(nodes == null){
			throw msg;
		}
		return isSerialize ? nodes.xml :nodes;
	}else if(document.implementation.hasFeature('XPath', '3.0')){
		// FF需要作进一步转换
		var resolver = this.createNSResolver(this.documentElement);
		var items	 = this.evaluate(xpathQuery, this, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		
		for(var i = 0, j = items.snapshotLength; i < j; i++){
		  nodes[i] = items.snapshotItem(i);
		}
		
		if(!nodes.length){
			throw msg;
		}
		
		return isSerialize ? new XMLSerializer().serializeToString(nodes[0]) : nodes;
	}
	
	return nodes;
}

保存日志格式为 XML的:

function log(log){
	var json, tmp;
	
	if(log.sql){
		tmp = log.sql;
		delete log.sql;
	}
	json = $$.XML.json2xml(log);
	
	var logItem = $$.xml.doc();
	if(!logItem.loadXML('<item>' + json + '</item>')){
		throw "生成日志XML文档时错误";
	}
	var value = logItem.createElement("value");
	var cd = logItem.createCDATASection(tmp);
	
	value.appendChild(cd);
	logItem.firstChild.appendChild(value);
	// 插入新的XML节点
	var xml = new ActiveXObject('Msxml2.DOMDocument.6.0');
	if(!xml.load(Server.Mappath('/app/public/log.xml'))){
		throw "保存日志XML文档时错误";
	}

	xml.lastChild.appendChild(logItem.firstChild);

	$$.XML.saveXML(xml);
	
	logItem = xml = value = cd = null;
	
	return true;
}

All XML Helper:

/**
 * @class
 * @singleton
 * 兼容浏览器与服务端的XML加载器。
 */
$$.xml = $$.XML = new (function(){
	
	/**
	 * 把 XML 格式转换为 JSON 输出。MS ONLY 暂时。
	 * @param	{IXMLDOMNode}	n
	 * @return	{Object}		JSON
	 */
	this.xml2json = function (node){
		var obj = {};
		var element = node.firstChild;
		while (element) {
			if (element.nodeType === 1) {
				var name = element.nodeName;
				var sub;
				
				sub = arguments.callee(element)
				sub.nodeValue = "";
				sub.xml = element.xml;
				sub.toString = function() {
					return this.nodeValue;
				};
				sub.toXMLString = function() {
					return this.xml;
				}
				// get attributes
				if (element.attributes) {
					for (var i = 0; i < element.attributes.length; i++) {
						var attribute = element.attributes[i];
						sub[attribute.nodeName] = attribute.nodeValue;
					}
				}
				// get nodeValue
				if (element.firstChild) {
					var nodeType = element.firstChild.nodeType;
					if (nodeType === 3 || nodeType === 4) {
						sub.nodeValue = element.firstChild.nodeValue;
					}
				}
				// node already exists?
				if (obj[name]) {
					// need to create array?
					if (!obj[name].length) {
						var temp = obj[name];
						obj[name] = [];
						obj[name].push(temp);
					}
					// append object to array
					obj[name].push(sub);
				} else {
					// create object
					obj[name] = sub;
				}
			}
			element = element.nextSibling;
		}
		return obj;
	}
	
	// @todo 需要吗?
	var Xml = {
		text: function(text) {
			return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")
		},
	
		attr: function(name, value) {
			return (name && value != null) ? (" " + name + "=\"" + this.text(value).replace(/"/g, /* "-->\x22 ? */ """) + "\"") : "";
		},
	
		cdata: function(text) {
			return (text) ? "<![CDATA[" + text.toString().replace("]>>", "]>>") + "]>>" : "";
		}
	};
	
	/**
	 * json2xml
	 */
	this.json2xml = function(obj) {
		var str = '';
		var tpl = '<{0} type="{1}">{2}</{0}>\n';
		
		function serialize(obj) {
			var fn	= arguments.callee;
			var xml	= [];
			var typ	= typeof obj;
			
			switch (typ) {
				case "object" : {
					if (obj === null) {
						xml.push("<" + i + " />\n");	// 空的闭合标签
					} else if (typeof obj.getTime === "function") {
						xml.push(tpl.format(i, 'date', obj.toUTCString()));
					} else if (typeof obj.join === "function") {
						for (var j = 0; j < obj.length; j++) {
							xml.push(fn(obj[j]));
						}
					} else {
						xml.push(tpl.format(i, typ, fn(obj)));
					}
					break;
				}
				case "string" :
					obj = obj.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
				case "date" :
				case "boolean" :
				case "number" : 
					xml.push(tpl.format(i ,typ, obj));
			}
			return xml.join("");
		}
		for (var i in obj) {
			str += serialize(obj[i]);
		}
		return str;
	}
		
	/**
	 * 兼容浏览器与服务端的XML加载器。注意,当前模式下关闭异步的通讯方式。
	 * create a document object
	 * @param	{String}	xml		XML文档路径或者XML文档片段。
	 * @param	{Boolean}	isNode	true表示为送入的为XML文档片段。
	 * @return {Object} the document
	 */
	this.loadXML = function(xml, isNode){
		var doc;
		
		if(typeof ActiveXObject != 'undefined'){
			doc = $$.xml.doc();
		}else if(typeof document != 'undefined' && !isNode){
			if(document.implementation && document.implementation.createDocument){
				doc = document.implementation.createDocument("", "", null);
			}  
		}else if(typeof DOMParser != 'undefined' && isNode){
			doc = new DOMParser().parseFromString(xml, "text/xml");		// 加载XML片段(Moliza Firefox)
			return doc;
		}
		
		if(!doc){
			throw '创建XML文档对象失败!';
		}
		
		doc.async = false;  // 关闭异步特性
		

		if		(xml && !isNode && (doc.load(xml) 	 == false)){		// 加载一份完整的XML文档(Moliza Firefox 与 IE均如此)
			throw '加载XML文档资源失败!';
		}else if(xml &&  isNode && (doc.loadXML(xml) == false)){		// 加载XML片段(IE)
			throw '加载XML片段失败!';									
		}
		
		return doc;
	}
	
	/**
	 * 定位某一XML节点。如果找不到则返回一空数组。
	 * 用法:
		var doc = loadXML('edk.xml');
		var xml = getNode.call(doc, '//head', false); 
	 * @param	{String}	xpathQuery	查询定位符。
	 * @param	{Boolean}	isSerialize	可选的,是否序列号查询结果为字符串,默认为true。
	 */
	this.getNode = function(xpathQuery, isSerialize){
		var nodes = [];
		var msg = 'NO Exist Node! 不存在匹配的节点,请检查输入的条件再作查询。';
		
		if(typeof isSerialize == 'undefined'){
			isSerialize = true;
		}
		
		if(typeof this.selectNodes != 'undefined'){
			nodes = this.selectSingleNode(xpathQuery);
			if(nodes == null){
				throw msg;
			}
			return isSerialize ? nodes.xml :nodes;
		}else if(document.implementation.hasFeature('XPath', '3.0')){
			// FF需要作进一步转换
			var resolver = this.createNSResolver(this.documentElement);
			var items	 = this.evaluate(xpathQuery, this, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			
			for(var i = 0, j = items.snapshotLength; i < j; i++){
			  nodes[i] = items.snapshotItem(i);
			}
			
			if(!nodes.length){
				throw msg;
			}
			
			return isSerialize ? new XMLSerializer().serializeToString(nodes[0]) : nodes;
		}
		
		return nodes;
	}
	
	/**
	 * perform an XLS transformation on an XML document and store the results in an element
	 * @param {Element} target the element to populate with the results of the transformation
	 */
	this.transform = function (xsltDoc, target){
		if(XSLTProcessor){
			var processor = new XSLTProcessor();
			processor.importStylesheet(xsltDoc);
			var doc = processor.transformToFragment(this, document);
			target.appendChild(doc);
		}else{
			target.innerHTML = this.transformNode(xsltDoc);
		}		
	}
			
	/**
	 * 依据数据值是什么(在 data 里查找匹配的),决定选中哪一个 Option 控件。
	 * @param	{IXMLDOMNode}	n		XML节点对象。
	 * @param	{Object}		data	数据对象。
	 * @return	{IXMLDOMNode}			XML节点对象。
	 */
	this.setSelectByNode = function(n, data){
        var i, k;
        var selectEl;
        
        for(i in data){
            k = ".//select[@name='{0}']".format(i);
            selectEl = n.selectSingleNode(k);
            if(selectEl){
                // 选中value一样的节点
                for(var z = 0; z < 2; z++){
                    if( selectEl.childNodes(z).attributes(0).value == data[i]){
                        selectEl.childNodes(z).setAttribute('selected', 'true'); // 设置为选中!
                    } 
                }
            }
        }
        return n;
	}
		
	/**
	 * 依据数据值是什么(在 data 里查找匹配的),决定选中哪一个Radio控件。
	 * @param	{IXMLDOMNode}	n		XML节点对象。
	 * @param	{Object}		data	数据对象。
	 * @return	{IXMLDOMNode}			XML节点对象。
	 */
	this.setRadioByNode = function(n, data){
        var 
         k
        ,selectEl;
        
        for(var i in data){
            k = ".//input[@name='{0}']".format(i);
            
            selectEl = n.selectNodes(k);
            if(selectEl && selectEl.length > 0){
                // 选中value一样的节点
                for(var z = 0; z < selectEl.length; z++){
                	// 默认attributes(3)是name属性
                    if( selectEl(z).attributes(1).value == data[i]){
                        selectEl(z).setAttribute('checked', 'true'); // 设置为选中!
                    } 
                }
            }
        }
        return n;
	}
	
	/**
	 * 从XML文档中选择指定的模板文件,将其数据绑定 data 输出。
	 * 有取消 CData 作转意之功能。
	 * @param	{String}	xmlFile	XML 片段或者是 XML 文件,需要完全的文件路径地址,一般需要 Server.Mappath() 获取真实地址后才输入到这里。
	 * @param	{String}	xPath 	XPath路径。
	 * @param	{Object} 	data	(可选的)数据实体,通常是 JSON 实体或者是配置文件 $$.cfg。
	 * @return	{String}			携带数据的HTML。
	 */
	this.from_XML_Tpl = function(xmlFile, xPath, data){
		var  
		 xml	= new ActiveXObject('Msxml2.DOMDocument.6.0')
		,node
		,tpl
		,html;

        // 自动判别是否可使用服务端的方法
		if(typeof Server != 'undefiend'){
			if(xml.load(Server.Mappath(xmlFile)) != true){
				throw '加载' + xmlFile + '模板文件失败';
			};
		}else{
			if(xml.loadXML(xmlFile) != true){
				throw '加载' + xmlFile + '片段失败';
			};			
		}
		
		node = xml.selectSingleNode(xPath);
		
		if(!node){
			throw '没有模板节点';
		}
		
		// Option的Selected属性等的居然没用完整XML陈述形式!!
		if(data){
			$$.XML.setSelectByNode(node, data);
			$$.XML.setRadioByNode(node,  data);
		}
   		
   		 tpl  = node.xml
   		,tpl  = tpl.replace('&', '&') // 规避XML标准的转义
   		,xml  = null
   		,html = data ? new Edk.Template(tpl).applyTemplate(data) : tpl;
   		
		// 由于有些地步不合XML WellForm标准,故用CData豁免之,先还原。
   		if(html.indexOf('<![CDATA[')){ 
   			html = html.replace('<![CDATA[', '').replace(']]>', '');
   		}
   		return html;
	}

	this.saveCDATA = function (){
		var post     = $$.form.post();
		var filePath = Server.Mappath($$.cfg.edk_root + '/app/form/staticPage.xml');
	    
	    var xml = new ActiveXObject('Msxml2.DOMDocument.6.0');
	    if(!xml.load(filePath)){
	        throw "打开模板文件错误";
	    }

		var parentNode = xml.selectSingleNode('//' + page.split('.').pop());
		var CDataNode  = xml.createCDATASection(post['Content']);
		parentNode.replaceChild(CDataNode, parentNode.childNodes(0));
		
		$$.XML.saveXML(xml, filePath);
		
		Response.Write('写入CData数据成功!');
		return true;
	}

	function setXML_cData(data, wrapTag, isCDATA){
		
		this.contentType = 'text/xml';
		
		if(typeof data == 'string'){
			if(wrapTag && !isCDATA){
				data = '<{0}>{1}</{0}>'.format(wrapTag, data);
			}else if(wrapTag && isCDATA){
				data = '<{0}>' + ("<![CD" + "ATA[") + "{1}" + ("]>" + ">")  + '</{0}>'.format(wrapTag, data.replace(("]>" +">"), "]>>"));
			}
			return data;
		}else{
			data = $$.XML.json2xml(data);
		}
		return datal		
	}
	
});

XML Class

$$.xml = {
	doc : function(){
		var doc;
		
		/**
		 * ActiveX Objects for importing XML (IE only)
		 * @type Array
		 */
		var MSXML = [
			"Msxml2.DOMDocument.6.0",
			"Msxml2.DOMDocument.5.0", 
			"Msxml2.DOMDocument.4.0", 
			"Msxml2.DOMDocument.3.0", 
			"MSXML2.DOMDocument", 
			"Microsoft.XMLDOM"   
		];
		
		for(var i = 0, j = MSXML.length; i < j; i++){
			try{
				doc = new ActiveXObject(MSXML[i]);
				break;
			}catch(e){}
		}
		
		return doc;	
	}

	/**
	 * 保存 XML 对象为 XML 文本文件。
	 * 注意:Server Side Only
	 * @param	{XMLDocument}	xmlDoc		XML 文档对象本身。
	 * @param	{String}		xmlFilePath	可选的。XML 文档的真实磁盘路径。
	 * @return	{Boolean}					是否操作成功。
	 */
	,save : function(xmlDoc, xmlFilePath){
	 	xmlFilePath = xmlFilePath || xmlDoc.url.replace(/file:\/\/\//,'');
	 	// make a clone
		var	saver = this.doc();
			saver.loadXML(xmlDoc.xml);
			
		if(	saver.readyState == 4 && saver.parsed){
			saver.save(xmlFilePath);
		}
		
		return true;
	}
		
	/**
	 * @param {String} node
	 * @param {String} str
	 */
	,saveCDATA : function (node, str){
		var parentNode = this.selectSingleNode(node);
		var CDataNode  = this.createCDATASection(str);
		parentNode.replaceChild(CDataNode, parentNode.childNodes(0));
		
		return true;// 写入CData数据成功!
	}
};

Model指的是一份XML文件,里面的某一段节点。这一段节点定义了域对象包含了哪几种字段。Model的定义是任意可设计的,依据业务对象的性质去安排。当前我们只读取input节点的定义,以别于其他无用的(相对的)HTML Markup。所以暂时借用了$$.vaildator表单验证器,但可以考虑在未来的版本中提供更全面的支持。该方法读取XML模型文件,获取模型。建议只读取一次,成为固定的属性,因为加载XML文件消耗资源。

启动该BO的特定方法。我们采用OO的方法论来规划后台的接口,也就是确定了业务对象是那个实体,然后执行对应的业务方法即可。 上述只是一个简单的步骤,细分之下,其中必然涉及复杂的浏览,这里就大致的讲一讲。 一般来说,每一个HTTP请求,服务端接纳后并执行的方法,就是这个方法。 每一个BO相当于是一个Action,也可以视作一个工作流的开始,就好像一个这样的流程如下: Action: Get HTTP post-->isSafe-->vaild-->permission-->do the job-->-->Response-->logging 除了do the job属于具体的业务方法外,其他走的都是一般的Web提交信息的后台所执行的工序。 大体设计上,该方法的作用有以下几点: 一、在此方法中完成了居于流程中前端的Get HTTP POST的工作。 getMethod的作用是依据请求,分拣出应该执行那个方法,因此返回的类型是Function。 换言之,具体执行的哪个方法,访问getMethod就可以知道。从一个侧面讲,getMethod具有明显的函数变量的特点,反映了当前方法的动态性。 this.actions是该BO的动作列表,须要传入到getMethod中,让getMethod从中选择。 getMethod()可支持经典的Web请求或者Ext.Diirect通讯模式。 有关$$.Entity.getMethod()的详细资讯,请参阅其文档。 二、开辟this管道。虽然getMethod()返还方法,但方法链已经不能支持args.callee, 只能除参数外选择其他方法实现信息通道,渗透控制工作流上每一个函数。好在JS有一个this管道,估计初衷是结合OO的遗留物, 现在FP的理念没想到有很好的作用。可以开辟参数以外的又一理想“寄存器”。不过推荐读取内容仍须经参数送入,写入的就可以这个this中进行,分工更加清晰。 三、此时马上就发挥this的作用。通过call(obj)实质就是决定了工作流内部每一个方法的this指针都是指向obj参数的。 (该参数为一“匿名对象”)。考虑到某些横向的对象引用,以此方便提取信息,当前提供user、domain等的管道在内。 该方法最终返还字符串,进而执行(在函数体外)Response.Write()输出到客户端输出内容或反馈信息。

* 结论1:Select * 语句对速度影响很大。 select * from Adab 用时:35940 (共57个字段) select xhjm,xm,xjztdm,bdm,nj,dwdm from Adab 用时 4186 select xhjm,xm from Adab 用时1626 select xm from Adab 用时830 *可以看得出每增加一个字段,时间会增加几乎是一倍。 * 另外,返回的数据的长度也会影响时间:如 select sfzh from Adab 用时1580 几乎与select xhjm,xm from Adab相同。 因此,返回的数据量是影响速度最关键的因素。网络上的数据传送成了执行SQL最大的性能问题。 执行一个selec dwdm,count(xhjm) from Adab的语句,用时106 要汇总计算,但传送数据少,因此速度很快



目录
相关文章
|
7月前
|
SQL XML 数据库
C#OOP之十六 开发常用之各种规范参考
C#OOP之十六 开发常用之各种规范参考
35 0
|
29天前
|
设计模式 前端开发 API
简述 Python WEB 开发常用的框架有哪些?
【2月更文挑战第26天】【2月更文挑战第88篇】简述 Python WEB 开发常用的框架有哪些?
|
2月前
|
JSON Rust 前端开发
Rust Web框架概览:Actix-Web与Yew的探索之旅
本文深入探讨了Rust编程语言中两个备受瞩目的Web框架:Actix-Web和Yew。我们将详细介绍这两个框架的核心特性、应用场景、性能优势以及如何使用它们构建高效、安全的Web应用。通过本文,您将更全面地了解Rust在Web开发领域的潜力和实践。
|
4月前
|
开发框架 数据可视化 前端开发
【Unity 3D】GameFramework、QFramework框架简介及应用实战(超详细 附源码)
【Unity 3D】GameFramework、QFramework框架简介及应用实战(超详细 附源码)
116 0
|
7月前
|
存储 Java API
从零开始学习 Java:简单易懂的入门指南之API、String类(八)
从零开始学习 Java:简单易懂的入门指南之API、String类(八)
|
10月前
|
API UED 网络架构
API入门指南:从零开始学习API的基础知识和应用
API(Application Programming Interface)指应用程序接口,是一种计算机软件接口,它使不同的应用程序之间可以进行交互。API已经在现代软件开发中变得越来越重要,因为它们允许应用程序之间实现无缝的集成,从而提供更优质的用户体验。
381 0
第四章 内嵌框架的使用
学习内置框架的使用与实践
100 0
第四章 内嵌框架的使用
|
JSON 监控 数据格式
netcore入门-基础
.NETCORE1.0出来了,咦不错,什么开源,跨平台的,观望下等2.0;我擦2.0出来了可以学习了,截止到目前2.1都快出来了,是时候学习一下了。 先建一个webapi项目,从简单的demo开始  项目结构总览    新面孔:1)launchSettings.
1309 0