写点什么

浅谈 dojox 中的一些小工具

  • 2011-10-10
  • 本文字数:3925 字

    阅读完需:约 13 分钟

不知道大家在使用 dojo 各种空间的同时,有没有关注一下 dojo 里面的各种工具包?有些工具包可能并不显眼,但是对我们的软件产品或者项目可能帮助甚 大,今天我简单说说 dojo extension(dojox)控件库里面的两个非常有用的工具包 — dojox.timing 和 dojox.string.

dojox.timing

首先来谈谈 timing。可能很多同学听都没有听过,不过我不得不说,他已经存在很久了。今天,我们分两部分来给大家讲解一下:

doLater

其实通过名字我们就能看出点大概 – “晚点再做”。事实上,他就是这个意思,我们来看看这个代码:

initCustomerWidget: function(){
if(dojox.timing.doLater(dojo.isObject(main.customerInfo), this, 200)){return;}
//TODO Code
this.jsondata = main.customerInfo;
… this.jsondata …

}

这是一段实际项目中的部分程序代码:页面初始化的时候会调用“initCustomerWidget”方法,然后初始化页面上的一些区域和内容,但是,这些内容需要从一个变量中取得“main.customerInfo”,然而“main.customerInfo”这个变量初始值为空,他的值需要在之前的一次向后台的异步 ajax 请求返回后才能拿到,当然:我们并不知道这个异步请求何时会返回。

OK,问题出现了,如何解决这个问题?这个时候“doLater”就派上大用场了。加了 “if(dojox.timing.doLater(dojo.isObject(main.customerInfo), this, 200)){return;}” 这段代码之后,“initCustomerWidget”的执行规则变成如下:

步骤 1. 如果“dojo.isObject(main.customerInfo)”为 false,“initCustomerWidget”便不会执行,但是 “200”毫秒以后会再次执行 “initCustomerWidget”, 并判断“dojo.isObject(main.customerInfo)” 的 true or false: 如果 false, 则回到 “步骤 2”,如果为 true,则到 “步骤 2”

步骤 2. “dojo.isObject(main.customerInfo)” 为 true 时则会执行接下来的代码:“TODO Code”

Sequence

相信大家在 web 开发中也经常会碰到需要延迟执行某端代码的需求,通常大家会用“setTimeout”这个方法,但是,如果有不只一段的代码需要延迟,而且出现延迟的代码里面还有延迟的情况,就会发现,如果我们仍然使用“setTimeout”,我们的代码的可读性就会大打折扣了。不用急,dojox 的 Sequence 工具就是来解决这个问题的,见如下代码:

复制代码
var seq = [
{ func: [showMessage, window, "i am first"], pauseAfter: 1000 },
{ func: [showMessage, window, "after 1000ms pause this should be seen"], pauseAfter: 2000 },
{ func: [showMessage, window, "another 2000ms pause and 1000ms pause before"], pauseAfter: 1000 },
{ func: [showMessage, window, "repeat 10 times and pause 100ms after"], repeat: 10, pauseAfter: 100 },
{ func: returnWhenDone } // no array, just a function to call
];
seqObj = new dojox.timing.Sequence({});
seqObj.go(seq, function() { logMsg('done') });

大家可以看到,我们只用定义一个“seq”对象,即可实现复杂延迟的功能,其中“func”用于传入需要延迟执行的函数 [函数, 作用域(scope), 参数(arguments)]。 “pauseAfter”表示延迟时间,“repeat”表示重复执行次数。可见,现在我们的代码是不是非常清晰,如果用“setTimeout”来写,将会是多么难读。

dojox.string

我们再来讲讲 dojox 的字符串(string)工具包,顾名思义,这个肯定是操作字符串的。可能有不少人对 java 中的操作字符串的方法记忆犹新,不少人对 C++ 的字符串操作方式较为熟悉。这里,dojox.string 包会把你带回到那个时代。

builder

我们先来看看 builder,大家应该都知道之前 java 推出的新工具 – StringBuilder,他几乎可以取代之前我们熟悉的 StringBuffer。这里也是一样,参看如下代码:

复制代码
var b = new dojox.string.Builder("foo");
b.append("foo");
b.appendArray([ "foo", "bar", "baz" ]);
b.replace("foo", "baz");
b.replace("o", "a").replace("b", "f");
b.insert(10, "awesome");
b.insert(0, "foo").insert(3, "bar").insert(3, "zoo");
b.remove(2, 100);
b.remove(5);

其实这些代码大家根据名字应该就能猜出来他是干什么的了,他几乎是模拟 java 的 StringBuilder 的做法。“appendArray”会把数组各个元素用“”连接起来,然后在 append 的之前的字符串上,insert 第一个参数是插入的位置,remove 第一个参数也是位置,第二个参数是指删除元素的字符数。

sprintf

再来看看 builder,学过 C 的人对这个再熟悉不过了,dojo 可以让你在开发 web 的时候同样有在写 C 的体验。参考如下代码:

复制代码
var sprintf = dojox.string.sprintf;
sprintf("% d", 42) --- " 42"
sprintf("% 15d", -42) --- " -42"
sprintf("%+d", 42) --- "+42"
sprintf("%05d", 42) --- "00042"
sprintf("%-15d", 42) --- "42 "
sprintf("%.2f", 42.8952) --- "42.90"
sprintf("%.10f", 42.8952) --- "42.8952000000"
sprintf("%06.2f", 42.8952) --- "042.90"

是不是回到了大学时代?这里的 sprintf 的用法与我们之前学的 C 语言的写法几乎一致。“0”表示缺位补 0,“-”表示空格补在右,"%.10f"表示小数点后保留 10 位,不足则补 0 等等… 你甚至可以把原先用 C 写好的代码直接复制过来,便可以跑在 web 页面上了。

我们再来看看 dojox 的 sprintf 的后续用法:

复制代码
sprintf("%1$s %2$s", "Hot", "Pocket") ---"Hot Pocket"
sprintf("%1$.1f %2$s %3$ss", 12, "Hot", "Pocket") ---"12.0 Hot Pockets"
sprintf("%(temperature)s %(crevace)s", { temperature: "Hot", crevace: "Pocket" })); ---"Hot Pocket"
sprintf("%0*.*f", 3.14159265, 10, 2) ---"0000003.14"
sprintf("%c", 36) ---'$'

似乎有点复杂了,其实不然,前两个相信大家都能明白,就是简单的顺序替换,可以把它们和第三个示例对比一下。有第三个示例我们可以看出,这里的 sprintf 可以传递 json 对象作为实参,其替换规则也很简单,就是简单的匹配:(temperature) 匹配 key 值 “temperature”。

对于“sprintf("%0*.*f", 3.14159265, 10, 2)”, 这里的第 2 和第 3 个参数用于指明前面的两个“*”号,所以翻译过来就是 “sprintf("%010.2f", 3.14159265)”,所以他的输出是"0000003.14"。

最后,对于 36,其字符数出为’$’,这个大家应该不奇怪了吧。

顺便说一下,dojox.string 里面的这些方法在性能上都做过优化,所以强烈推荐大家使用。

dojox.validate

我们再来讲讲 dojox 的验证(validate)工具包。不知道大家是不是有时候会为写某一些 javascript 的验证脚本而费尽心思,担心无法覆盖到所有的情况?如果有,那么 dojox 的验证工具包将会是您的首选。这个工具包里面包含了几乎所有的比较流行,常用的一些验证方法,如邮箱,ip,电话号码,邮编等等等等。你不再需要为某些验证花费时间和代码量了,你只需要添加一行代码即可。

validate

这是 validate 工具包的基础,包括很多最基本的验证工具:

复制代码
tests.t(dojox.validate.isValidIsbn('0-596-00759-0'));
tests.t(dojox.validate.isText(' x '));
tests.f(dojox.validate.isIpAddress('024.17.155.040'));
tests.f(dojox.validate.isUrl('http://.yahoo.com'));
tests.f(dojox.validate.isEmailAddress('x@yahoo'));
tests.t(dojox.validate.isInRange( '1', {min: 1, max: 100} ));
tests.t(dojox.validate.us.isPhoneNumber('111/111-1111'));
tests.f(dojox.validate.us.isSocialSecurityNumber('123-45 6789'));
tests.t(dojox.validate.us.isZipCode('123456789'));
tests.f(dojox.validate.ca.isPostalCode('1AZ 3F3'));

我们来一一介绍:

  1. “isValidIsbn” 判断是否为国际标准书号。国际标准书号(International Standard Book Number)简称 ISBN。
  2. “isText” 判断是否是合格字符串, 注:全为空格则不合格
  3. “isIpAddress”, “isUrl”,“isEmailAddress”, “isPhoneNumber”都很简单,不做过多介绍。
  4. “isSocialSecurityNumber”, “isZipCode”, “isPostalCode”等等分别为社保号,邮编,注意这里他们都有国家限制,有的是美国 “us.isSocialSecurityNumber”, 有的是加拿大 “ca.isPostalCode(‘1AZ 3F3’)”。

creditcard

这是专门针对信用卡的验证:

复制代码
tests.t(dojox.validate.isValidLuhn('5105105105105100')); //test string input
//Visa 卡 cvv 验证
tests.t(dojox.validate.isValidCvv(421,'vi'));
//American Express 卡 cvv 验证
tests.t(dojox.validate.isValidCvv('1234','ax'));
tests.f(dojox.validate.isValidCvv(43215,'ax'));
//Visa 卡号验证
tests.t(dojox.validate.isValidCreditCard('4111111111111111','vi'));
tests.t(dojox.validate.isValidCreditCard('4111111111010','vi'));
//American Express 卡号验证
tests.t(dojox.validate.isValidCreditCard('378 2822 4631 0005','ax'));
tests.t(dojox.validate.isValidCreditCard('341-1111-1111-1111','ax'));

可以参见上述注释,其中

  1. “CVV”,即 Card Verification Value,是由卡号、有效期和服务约束代码生成的 3 位或 4 位数字,一般写在卡片磁条的 2 磁道用户自定义数据区里面,通常作验证用途。
  2. “isValidCreditCard” 与 “isValidCreditCardNumber” 接口功能类似,可通用。

还有一些验证专门用于巴西等国家,这里不做介绍。


感谢张凯峰对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2011-10-10 00:003102

评论

发布
暂无评论
发现更多内容

某程序员哀叹:写几年代码,回头一看80%都没用,没法写上简历!

Java你猿哥

Java 程序员 面试 简历

Postman Runner 使用指南

Liam

Java 后端 Postman 接口测试 API 开发

Linux 修改系统时间的两种方式

会踢球的程序源

Java Linux

研究思考丨关于软件复杂度的困局

阿里巴巴云原生

阿里云 云原生 复杂度

运维审计录像的作用是什么?用什么软件好?

行云管家

堡垒机 运维审计 审计录像

600+ 道 Java面试题及答案整理(建议收藏)

会踢球的程序源

Java 面试 java面试 应届生 Java八股文

技术分享 | 如何迅速将分布式政企应用转型为云原生微服务架构

IT科技苏辞

SOA/ESB架构升级之路:从微服务到ServiceMesh,再到Sermant

IT科技苏辞

华为云智能编程助手助力哈尔滨工业大学(深圳)培养新时代软件研发人才

爱尚科技

PostgreSQL技术内幕(七)索引扫描

酷克数据HashData

数据库 postgresql

互联网工程师Java面试八股文及答案整理(2023最新版)

Java你猿哥

Spring Cloud springboot java面试 面经 JVM面试

云服务是什么意思?有什么用?

行云管家

云计算 云服务

爆肝一月!527页文档详解SpringCloud微服务和分布式系统实践

Java你猿哥

数据库 分布式 SSM框架 微服务设计

【经验分享】硬件工程师需要知道的DFM可制造性设计

华秋PCB

工具 电路 PCB PCB设计 可制造性

【Linux】系统中安装Go环境

A-刘晨阳

Go Linux 三周年连更

实战分享丨 MySQL 与 Django 版本匹配相关经验

Java你猿哥

Java MySQL SSM框架 实战 Diango

涅槃重生!字节大牛力荐大型分布式手册,凤凰架构让你浴火成神

Java你猿哥

架构 分布式架构 凤凰架构

Databend v1.1 版本发布!

Databend

大咖力荐 |《中国企业软件研发管理白皮书》为什么值得看?

万事ONES

ElasticSearch 高级检索,按照顺序进行搜索

alexgaoyh

elasticsearch dsl 顺序搜索 高级检索 与或关系

解析单存储库:定义、优势与挑战

龙智—DevSecOps解决方案

谷歌 Monorepo Monolith 单储存库

分布式文件系统FastDFS

会踢球的程序源

Java fastdfs 分布系统

打造安全无忧软件应用的十大最佳实践

龙智—DevSecOps解决方案

软件开发 软件开发安全

分布式政企应用如何快速实现云原生的微服务架构改造

IT科技苏辞

华为云智能编程助手赋能高校,揭示行业发展新动向

爱尚科技

缓存一致性设计思路

我爱娃哈哈😍

redis 缓存 缓存一致性

关于自托管环境,您了解多少?

龙智—DevSecOps解决方案

Atlassian Data Center

阿里高工纯手写的《分布式架构手册》仅仅一天GitHub就标星128K

Java你猿哥

架构 分布式 分布式架构

OneCode 开源集成开发工具ESD功能介绍

codebee

开源 低代码平台

ReentrantLock和Synchronized使用与区别,多线程安全问题

共饮一杯无

synchronized ReentrantLock 三周年连更

解决流水线瓶颈、提升编码效率的五个方法(上篇)

龙智—DevSecOps解决方案

ci cicd 持续集成 流水线

浅谈dojox中的一些小工具_Java_周翔_InfoQ精选文章