我以前实现的@DBLooup AJAX版,都是通过URL带参数,执行后台代理,并返回结果的方式。最近在实现一个应用模块时,看到我们公司同事的实现方式,觉得比我的更好一些,但有些缺陷。特此将代码贴出来供大家参考。具体的JS代码如下:

show source
01function dblookup(view,skey,column){  
02    try{  
03        var url = getPath()+"/"+view+"?readviewentries&restricttocategory="+skey;  
04        objHTTP = new ActiveXObject("Microsoft.XMLHTTP");  
05        //下面用get方法,在get方法中,代理取传过去的参数是用doc.query_string(0)  
06        objHTTP.open("GET", vurl, false, "", "");  
07        objHTTP.setRequestHeader("If-Modified-Since","0");  
08        objHTTP.send(false);  
09        //此处调用的是同步方法  
10        resp = objHTTP.responseXML.documentElement;  
11        objHTTP = null;  
12        var ss="";  
13        if (resp.hasChildNodes()) {  
14            NodeList = resp.getElementsByTagName("viewentry")  
15            for (var k=0;k
16                NodeList1=NodeList(k).getElementsByTagName("entrydata");  
17                mynode=NodeList1(column-1).firstChild;  
18                mynode1=mynode.firstChild;  
19                ss= mynode1.nodeValue;  
20                break;  
21              }  
22          }else{  
23                ss="";  
24          }  
25    }catch(e){  
26        ss="";  
27    }  
28    return ss;  
29}

以上代码在使用URL请求视图时,使用restricttocategory进行分类限制,这样可以得到以skey为分类的视图,再通过返回的XML文档,对其进行解析得到视图中第一份文档指定列(column)中的值,并返回给调用者;

如果你想返回多个文档的指定列值,将: 
                ss= mynode1.nodeValue; 
                break; 
      修改为: 
                ss+=";"+mynode1.nodeValue; 
      即可。但需要注意,视图缺省只返回20个文档,相关设置在服务器文档中设置。需要返回超过20个文档时,你可以在请求的URL中加入count参数来指定需要返回文档的个数。

此函数缺点不利于扩展,假如dblookup函数已在项目中或产品模块实施,但现在需要将其功能进行扩展,加入跨库和跨服务器功能时,如果修改dblookup函数参数,则肯定会影响到现在项目中或产品模块中相关的JS代码,对升级或更新造成了不少的工作量,这些工作量又是重复的。这种情况下通常选择的是新增另一个函数,如dblookup_pro,这样会使封装的JS文件多一些冗余代码,从而增加JS文件尺寸。当然你会说,增加一个函数并不会增加JS文件多少尺寸,但你想想,都抱着这个心态,JS中这扩展点,那补充点。经过长期团队成员的修改和项目积累,会使用封装的JS文件会越来越大,到达一种冗余代码过多,但又不得不用的状态。所以我一直强调在设计通用代码时,一定要适当考虑代码容错和以后的功能扩展对现有代码的影响。这样会给今后代码维护带来非常小的工作量,虽然前期在写代码考虑的事情非常多,但你如果习惯了这种代码编写风格,会规范你的代码,提高你代码的质量,这不是每位程序员所追求的吗?

但以上代码看似正常,能运行很好。但并没有容错代码,如HTTP请求失败,视图不存在怎么办?从代码上看返回的是空值,但这个是正确的返回结果吗?但如果出现以下情况,就会出现不可估量问题:

在提交文档时,如果调用dblookup,会有可能因为网络延时造成,未返回结果就已提交文档了。如下代码片断:

show source
1......  
2document.forms[0].UserCN.value = dblookup(‘vwAllUsers’,'SquallZhong',2);  
3document.forms[0].submit();

以上代码有可能让UserCN的值为空,如果在WebQuerySave()事件中有读UserCN域的值对文档进行处理,会造成程序上的运行错误。

对dblookup进行改进后,代码如下:

show source
01function dblookup() {  
02    //返回字符串  
03    var ret = null;  
04    //视图别名  
05    var vn = arguments[0];  
06    if (vn == null || vn == "") {  
07        alert("\u8bf7\u6307\u5b9a\u89c6\u56fe\u522b\u540d\uff01");  
08        return ret;  
09    }  
10    //关键字  
11    var key = arguments[1];  
12    if (key == null || key == "") {  
13        alert("\u8bf7\u6307\u5b9a\u5173\u952e\u5b57\uff01");  
14        return ret;  
15    }  
16    //指定列名  
17    var col = arguments[2];  
18    if (col == null || col == "") {  
19        alert("\u8bf7\u6307\u5b9a\u5217\u503c\uff01");  
20        return ret;  
21    }  
22    //回调函数  
23    var func = arguments[3];  
24    //指定数据库路径,数据库路径请使用Apps/DB.nsf。  
25    //不论在WINDOW平台还是LINUX平台,在Domino平台中可使用"/"通用,并兼容URL格式  
26    var dbpath = arguments[4];  
27    //如果未指定数据库路径,则取当前路径  
28    if (dbpath == null || dbpath == "") {  
29        dbpath = getPath();  
30    }  
31    //将数据库路径中""转换为"/"  
32    dbpath = dbpath.replace("\\", "/");  
33    //指定数据库所在服务器名称,如AS1/ACME  
34    var svr = arguments[5];  
35    try {  
36        var url = "";  
37        if (svr == null || svr == "") {  
38            url = "/" + dbpath + view + "?readviewentries&restricttocategory=" + skey;  
39        } else {  
40            //如果为跨DOMINO服务器请求,使用后台代理处理跨服务器请求  
41            url = "/vgoresource.nsf/dblookup?openagent&login";  
42            url += "&vn=" + vn;  
43            url += "&key=" + key;  
44            url += "&col=" + col;  
45            url += "dbpath=" + dbpath;  
46            url += "svr=" + svr;  
47        }  
48        // 避免IECache,添加时间戳  
49        url += "&__t=" + Math.random();  
50        var objHTTP = null;  
51        if (window.XMLHttpRequest) {  
52            // 创建 Mozilla/FireFox平台的 XMLHttpRequest 对象  
53            objHTTP = new XMLHttpRequest();  
54        } else {  
55            if (window.ActiveXObject) {  
56            // 创建 IE/Windows 平台的XMLHttp对象  
57                objHTTP = new ActiveXObject("Microsoft.XMLHTTP");  
58            }  
59        }  
60        objHTTP.open("GET", url, false);  
61        objHTTP.onreadystatechange = function () {  
62            if (objHTTP.readyState == 4) {  
63                if (objHTTP.status == 200) {  
64                    //如果有回调函数  
65                    if (callback != null) {  
66                        var resp = objHTTP.responseXML.documentElement;  
67                        if (resp.hasChildNodes()) {  
68                            var NodeList = resp.getElementsByTagName("viewentry");  
69                            for (var k = 0; k < NodeList.length; k++) {  
70                                NodeList1 = NodeList(k).getElementsByTagName("entrydata");  
71                                mynode = NodeList1(column - 1).firstChild;  
72                                mynode1 = mynode.firstChild;  
73                                ret = mynode1.nodeValue;  
74                            }  
75                        } else {  
76                            ret = null;  
77                        }  
78                        callback(ret);  
79                    } else {  
80                        //如果没有回调函数,直接返回文本  
81                        return objHTTP.responseText;  
82                    }  
83                } else {  
84                    return null;  
85                }  
86            }  
87        };  
88        objHTTP.send(null);  
89    } catch (e) {  
90        return null;  
91    }  
92}

经过整改后的代码,可实现:

dblookup(view,keystring,column-num[,callback-function[,dbpath[,servername]]]
view:视图别名 
keystring:关键字查询 
column-num:指定列数 
callback-function:回调函数(可选) 
dbpath:指定数据库路径(可选),缺省为当前数据库 
servername:指定Domino服务器名称(可选),缺省为当前服务器;注:指定服务器名称时,请不要使用CN=Apps/O=ACME,这样在URL地址相加时会认为是两个参数,所以指定服务器名称时请使用Apps/ACME 
方括号中为可选参数。这样可兼容以前项目所使用的dblookup(view,keystring,column-num),不需要维护已有WEB应用中调用的格式,也能实现回调函数处理功能/跨库/跨服务器功能。 
有了回调函数功能,可避免在AJAX请求未完成之前,执行下面的代码,从而提高了代码的容错性,如下列代码:

show source
01.......  
02function savedoc() {  
03    //查询是否已定义过,并回调继续提交函数  
04    var key = f.StServerName.value + "!!" + f.StDBPath.value;  
05    key = key.split("\\").join("/");  
06    dblookup("ArchivePolicyViewByFullDBPath", key.toLowerCase(), 1, submitdoc);  
07}  
08function submitdoc() {  
09    var ret = arguments[0];  
10    var f = document.forms[0];  
11    if (ret == null) {  
12        f.submit();  
13    } else {  
14        alert("此数据库的归档策略已定义,请重新输入数据库路径!");  
15        f.StDBPath.select();  
16        f.StDBPath.focus();  
17    }  
18}

后续问题考虑:

1.dblookup函数中处理是使用XML文档解析方式,如果你使用的Domino服务器是7.0以上版本,建议使用JSON来处理数据,这样效率要比XML解析效率高。如果使用JSON来处理数据,需要将视图输出格式修改为JSON输出,只需要将以下代码: 
url = "/" + dbpath + view + "?readviewentries&restricttocategory=" + skey; 
修改为: 
url = "/" + dbpath + view + "?readviewentries&outputformat=json&restricttocategory=" + skey; 
注:还需要修改对JSON数据的解析方式

2.此函数功能,并未实现根据关键字查询相应文档所指定的域名,如果哪位朋友有兴趣可以实现一下。

3.Domino中视图设置,视图中第一列必须为分类列,如果第一列不是分类列,是查不出结果的。如下图: 

4.对于封装的JS文件,建议对其进行混淆和压缩,来提高Javascript的安全性和JS在网络中的传输速度。

参考资料:

1.JS混淆压缩工具:http://blog.csdn.net/SquallZhong/archive/2008/11/29/3410592.aspx

2.WEB性能优化及考虑:http://blog.csdn.net/SquallZhong/archive/2008/08/25/2826429.aspx

转载于:https://www.cnblogs.com/hannover/archive/2011/05/29/2062008.html

从Domino公式@DBLookup Web化谈如何实现通用函数相关推荐

  1. 【华为云技术分享】全WEB化开发体验,开发者新利器华为云CloudIDE即将揭秘

    随着公有云的不断普及,无论是企业办公.社交网络,还是线上娱乐都越来越依赖云上提供的各种服务,微服务.DevOps.持续交付.容器化等云原生技术和理念也在企业上云大背景下不断对现有的开发活动以及开发工具 ...

  2. 【CAD-Web】CAD/DWG的Web化

    2022.11.19更新. 一.背景 近期需要做个信息系统,能将一些2D的平面示意图(DWG格式文件)放到Web上,供放大.浏览,甚至可对元素进行交互,如点击.拖动.改变元素颜色线条等.于是,需要寻找 ...

  3. 送给SQL开发者的一份新年礼物!麦聪软件发布一款纯Web化SQL开发工具,免安装还免费!

    2023年新年伊始,麦聪软件再次迎来一个好消息:一款100%自主研发的纯Web化SQL开发工具--SQL Studio 1.0正式发布.这款产品让SQL开发者在Navicat.DBeaver之外,又多 ...

  4. SQL Studio:一款纯Web化SQL开发工具,关键是免安装还免费!

    经常使用SQL工具的开发者对Navicat一定都不陌生.这款软件作为一款全球化的多数据库管理工具,这些年逐步得到全国各地SQLer(SQL开发者)的关注. 与其他很多外来的软件产品一样,由于价格原因, ...

  5. 素数计数公式全面拉丁化改写-小有改进-Meissel公式-梅塞尔-Lehmer公式-莱梅=勒梅尔-筛法三种形式-孟庆余公式(转载)...

    何冬州的百度空间Blog   本文的另一版本:  http://hi.baidu.com/wsktuuytyh/blog/item/396a934ac679680208f7ef2c.html    信 ...

  6. 一款纯Web化免费SQL工具,重新定义数据库管理

    SQL Studio是一款由麦聪软件研发的多数据库管理工具,提供Windows.Linux 和 MacOS三种版本的软件包,支持中英文两种语言.SQL Studio是用Java编写的,默认使用 JDK ...

  7. Cmdb、Saltstack、Web化,莉莉丝游戏云上运维心得分享

    在2017游戏行业全球同服和安全攻防技术沙龙上,来自莉莉丝游戏的蒋海洋分享了<莉莉丝游戏云上运维之路>.他通过介绍莉莉丝游戏的概况.进化历程,引出了莉莉丝游戏使用的cmdb,Saltsta ...

  8. pythonweb开发-Web | 浅谈用Python进行Web开发

    Web开发这样一个大概念,对我这种小白来说,想学也不知道从哪下手.在网上广泛地浏览了一下这个方面的文章后,我发现当今Web开发的一大热门语言是Python(最大的当然还是PHP),而恰好我平常用Pyt ...

  9. 数字逻辑代数基础——基本定理、公式与卡诺图化简法、格雷码、LSFR等

    复习一下数字电路,下次就省事直接看自己写的了. 目录 1.常用门电路图 2.逻辑代数的基本定理----化简时比较好用 3.化简逻辑函数时几个关键的公式(A'代表A的非) 4.格雷码与二进制的转换 5. ...

最新文章

  1. python制作神经网络_python_deeplearning02_使用python制作神经网络
  2. Visual Studio2017 安装教程(走过的坑绝不再走)
  3. [云炬创业基础笔记]第六章商业模式测试11
  4. 发一个自己写的抓包软件,支持插件化脚本分析
  5. 转自: http://blog.csdn.net/xiaxiaorui2003/article/details/3838631
  6. HP380 G9服务器RAID划分
  7. Django(6)-orm
  8. 信息安全学习笔记(五)------计算机病毒
  9. <研赛>华为杯数学建模竞赛获奖经验分享--数模之星提名
  10. Linux代码比对工具meld
  11. A/Btest (A/B测试)的营销策略效果分析
  12. 家的温暖社会实践报告
  13. 2020年计算机竞赛姜子敬,初赛公示_2020年全国高校计算机能力挑战赛
  14. css清除浮动大全,共8种方法。
  15. Android平台安全分析
  16. lombok插件的使用
  17. 深入理解Java集合框架
  18. JavaScript 字符串转日期多八个小时的解决
  19. by which, in which, from which...
  20. 如何把传真机连接电脑当打印机使用?

热门文章

  1. 第8章、注意力机制与外部记忆
  2. 解决多卡加载预训练模型时,卡0总会比其他卡多占用显存,多卡占用显存不均
  3. 人生苦短,我用python实现人脸(口罩)识别(及时行代码搞定)
  4. 艾司博讯:拼多多诱导非官方交易有哪些处理?
  5. [day2]python网络爬虫实战:爬取美女写真图片(增强版)
  6. 机器学习——入门基础
  7. STM32学习笔记01---使用仿真器下载程序
  8. java中applet是什么意思_Java Applet与Java Application的区别
  9. 双重游标的使用以及动态游标的使用
  10. Python爬取扇贝“【无老师】7天搞定TOEFL单词”