欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

面向对象JS编程基类实现

程序员文章站 2022-10-27 14:53:37
web打印(3),面向对象js:名字空间、类定义、继承、xml分析xmlparserbase基类实现 javascript代码,可以写在html里,也可以写在*.js文件里,大家没有有遇到引用了别人...

web打印(3),面向对象js:名字空间、类定义、继承、xml分析xmlparserbase基类实现

javascript代码,可以写在html里,也可以写在*.js文件里,大家没有有遇到引用了别人或自己的js文件时,发现定义了同样的变量,例如 var myobject;

由于javascript不像c#是强类型面向对象编程语言,更多的是像c的过程性结构化编程语言,随处定义变量,不可避免定义重复的变量名,这种重复的变量会导致严重的后果。所以,像c#一样,引入名字空间,将类定义到名字空间下,将变量定义到类中,不同类,定义了相同的变量互不受影响。

面向对象最大的特点是抽象,最大优点是可复用性。既然是做打印元素,例如文本、标签、表格、图片、标尺等等,他们都有一个共同的特征,就是用xml去描述他们的属性特点,而分析xml后,获得一个打印对象。所以,xmlparserbase基类,抽象了xmlnode,作为类的属性,然后继承ixmlparser,实现接口定义的方法parser(),分析xml后将相关标签写入tag属性。由于后续要做大量的xml分析,所以,xmlparserbase基类,提供读取xml文件、xml字符串、xml节点的大量实用方法,供继承于xmlparserbase的子类使用。

字空间
/*顶层命名空间*/
var goldprinter =goldprinter || window.goldprinter || {};
/*子命名空间,可嵌套定义*/
goldprinter.drawing = goldprinter.drawing || window.goldprinter.drawing || {};
goldprinter.xmlparser = goldprinter.xmlparser || window.goldprinter.xmlparser || {};
以上定义方法需要说明的是,以var goldprinter =goldprinter || window.goldprinter || {}为例,在重复定义goldprinter时避免被误覆盖掉。这样便能很方便的在多个文件里定义命名空间了。 类定义

在上文web打印(2),打印核心架构--xml分析器及打印元素uml类图,接口及实现中,其实已定义了ixmlparser类,并且用js实现ixmlparser时,我们用到了如下语句:
goldprinter.throw.msg("这是ixmlparser的parse() ,接口类不要实例化!\r\n类型:" + typeof (this) + "真实类名" + this.gettype());

这其实是调用于goldprinter名字空间下throw类的一个msg()方法。在后续的开发实现中,我们经常用于如下两个类,类似c#的静态类及静态方法。
goldprinter.throw = { msg: function (message) { alert(message);} };
goldprinter.messagebox = { show: function (message) { alert(message); }, debug: function (message) { alert(message); } };

throw 类专门用于抛出异常时对话框,以提示开发者自己,messagebox类用于显示对话框,用于提示客户端正在使用的操作用户。

综述,ixmlparser类和throw、messagebox类,是两类不同写法的类。前者相当于是一个模版,可以复制出很多具有相同模版又可以改变模版中属性值的对象,这种类可实例化,只能使用实例对象;而后者,不用把模版复制直接可以使用。 继承

/*
* 表示分析处理用xml节点描述特征的对象的基类。
*/
jxmlparser.xmlparserbase = function (xmlnode, tag) {

//模拟c#,获取实例的类型,js如果不实现,都返回object
this.gettype = function () { return "goldprinter.xmlparser.xmlparserbase"; };

/*获取或设置描述对象特征的xml节点。*/
this.xmlnode = "";
/*获取或设置报表设计器的类型。*/
this.reportdesigner = jxmlparser.reportdesigner.goldprinter;
//标签
this.tag = {};

if (xmlnode) {
this.xmlnode = xmlnode;
}
if (tag) {
this.tag = tag;
}

//其他代码..

}

//继承于接口ixmlparser
jxmlparser.xmlparserbase.prototype = new jxmlparser.ixmlparser();
说明:
jxmlparser.xmlparserbase = function (xmlnode, tag) {},用于定义一个类xmlparserbase ,他在goldprinter.xmlparser名字空间下,名字空间简写为jxmlparser。
new jxmlparser.ixmlparser();表示创建ixmlparser的一个实例,将xmlparserbase的原型指向这个实例,这种实现继承的方法叫“原型链”法。

xmlparserbase基类实现
下面是其实现的全部js代码。

/*
* 表示分析处理用xml节点描述特征的对象的基类。
*/
jxmlparser.xmlparserbase = function (xmlnode, tag) {

//#region 实现...

//模拟c#,获取实例的类型,js如果不实现,都返回object
this.gettype = function () { return "goldprinter.xmlparser.xmlparserbase"; };

/*获取或设置描述对象特征的xml节点。*/
this.xmlnode = "";
/*获取或设置报表设计器的类型。*/
this.reportdesigner = jxmlparser.reportdesigner.goldprinter;
//标签
this.tag = {};

if (xmlnode) {
this.xmlnode = xmlnode;
}
if (tag) {
this.tag = tag;
}

/*对tag进行分析,并附加上reportdesigner,如果需要可以调用,一般无用。*/
this.tagparse = function () {
//#region 实现...
var node = this.getxmlnode();
if (node) {
//在属性中搜
var otag = this.getxmlnodeattributevalue(node, "tag");
var oreportdesigner = this.getxmlnodeattributevalue(node, "reportdesigner");
//属性中没,在子节点中
if (otag == "") {
otag = this.getxmlnodechildnodevalue(node, "tag");
}
if (oreportdesigner == "") {
oreportdesigner = this.getxmlnodechildnodevalue(node, "reportdesigner");
}
if (otag != "") {
this.tag = otag
}
if (oreportdesigner != "") {
this.reportdesigner = oreportdesigner;
}
}
//#endregion 实现...
};

this.parse = function () {
//js方法,不会调用基类已重写的方法。所以,继承此类的方法,重写parse时,手动强制调用parentclass.parse()
this.tagparse(); //c#中xmlparserbase是抽象类,所以没有放在模板方法中调用
goldprinter.debugmodel.msg("这是xmlparserbase的parse() ,抽象类,请在子类实现parse()方法!\r\n类型:" + typeof (this) + "真实类名" + this.gettype());
return this;
};

var mxmlparsenode = undefined;
/*获取xmlnode,当其为xml字符串时,自动将期转换为节点,将缓存,如果重新改变了xmlnode不使用缓存,则要调用setxmlnode()*/
this.getxmlnode = function () {

var node = mxmlparsenode;
if (node == undefined) {
node = this.xmlnode;
}
else {
return mxmlparsenode;
}

if (node && typeof (node) == "string") {
node = this.selectrootnode(node, false);
//缓存
mxmlparsenode = node;
}

return node;
};

/*设置xmlnode属性,并清空节点缓存*/
this.setxmlnode = function (xmlnode) { mxmlparsenode = undefined; this.xmlnode = xmlnode; };

/*用xml文件设置元素,xmlnode属性默认取其根结点,第一参数表示表示金质打印通的元素集合文件或文件文本内容,第二参数为true,表示文件名,否则为文件具体内容*/
this.selectrootnode = function (xmlfilename, isxmlfileorcontext) {
//#region 实现...

//
if (xmlfilename == undefined) return;

var isxmlcontext = xmlfilename;

if (isxmlfileorcontext) {
if (window.xmlhttprequest) {// ie7+, firefox, chrome, opera, safari
xmlhttp = new xmlhttprequest();
}
else {//ie6, ie5
xmlhttp = new activexobject("microsoft.xmlhttp");
}
xmlhttp.open("get", isxmlcontext, false);
xmlhttp.send();
mxmldoc = xmlhttp.responsexml;
}
else {
/*
//不是xml文件,而只是一个节点,则加上 \u003cxml version=\"1.0\" encoding=\"utf-8\"\u003e
if (isxmlcontext.indexof("

isxmlcontext = "\u003cxml version=\"1.0\" encoding=\"utf-8\"\u003e" + isxmlcontext;
}
*/

if (window.domparser) {//firefox, chrome, opera, safari
parser = new domparser();
mxmldoc = parser.parsefromstring(isxmlcontext, "text/xml");
}
else {// internet explorer
mxmldoc = new activexobject("microsoft.xmldom");
mxmldoc.async = "false";
mxmldoc.loadxml(isxmlcontext);
}
}
var rootnode = mxmldoc.documentelement;
//rootnode.childnodes[i]
return rootnode;
//#endregion 实现...
}

//根据节点属性名取得节点对象,属性名不区分大小写,找不对则返回null。
this.getxmlnodeattributebyname = function (node, findattributename) {
//#region 实现...
if (node) {
var attributename = "";
for (var i = 0 ; i < node.attributes.length; i++) {
attributename = node.attributes[i].name.tolowercase();

if (findattributename.tolowercase() == attributename) {
return node.attributes[i];
}
}
}
return null;
//#endregion 实现...
};

//读取节点的属性值,如果属性不存在则返回空串""。
this.getxmlnodeattributevalue = function (node, attributename) {
//#region 实现...
if (node) {
var attribute = this.getxmlnodeattributebyname(node, attributename);
if (attribute) {//attribute.nodetype == 2
return attribute.value; //attribute.nodevalue
}
}
return "";
//#endregion 实现...
};

// 根据子节点名取得节点的子节点对象,子节点名不区分大小写,找不对则返回null。
this.getxmlnodechildnodebyname = function (node, childnodename) {
//#region 实现...
if (node) {
var son = undefined;
var sonname = undefined;
var childnodevalue = undefined;

for (var i = 0 ; i < node.childnodes.length; i++) {
son = node.childnodes[i];
sonname = son.nodename;
if (son.nodetype != 1 || sonname == undefined) {
continue;
}
sonname = sonname.tolowercase();
if (sonname == childnodename.tolowercase()) {
return son;
}
}
}
return null;
//#endregion 实现...
};

//读取节点子节点的值,如果不存在则返回空串""。
this.getxmlnodechildnodevalue = function (node, childnodename) {
//#region 实现...
if (node) {
var childnode = this.getxmlnodechildnodebyname(node, childnodename);

if (childnode) {
return childnode.textcontent;
}
}
return "";
//#endregion 实现...
};

// 选择匹配xml文档中指定节点标记名的第一个节点。注意节点名区分大小写的。
this.selectsinglenodebynodename = function (xmlfilename, nodename) {
if (node) {
goldprinter.throw.msg("实现ing");
}
return undefined;
};

// 在xml文档中查找匹配节点标记名指定属性值的第一个节点。注意节点名属性及值都是区分大小写的。
this.selectsinglenodebyattribute = function (xmlfilename, nodename, attributename, attributevalue) {
if (node) {
goldprinter.throw.msg("实现ing");
}
return undefined;
};

/*只为与c#保持一致,在js意义不大。c#中从预定义的颜色名如red、gold或十六进制的颜色如#0000ff或以逗号分隔的三色值,如255,255,255 创建一个system.drawing.color结构。*/
this.getcolorfrom = function (color) {
if (color) {
var arr = color.split(',');
if (arr.length >= 2) {
if (color.tolowercase().indexof("rgb") < 0) {
return "rgb(" + color + ")";
}
}
return color;
}
return "black";
};

}

//继承于接口ixmlparser
jxmlparser.xmlparserbase.prototype = new jxmlparser.ixmlparser();