微信号:infoqchina

介绍:有内容的技术社区媒体

使用decj简化Web前端开发(二):声明式表单增强和页面初始化

2013-10-28 16:06 黄文海

引言


表单(Form)是Web应用中数据展现和收集常用的HTML元素。开发人员经常需要处理表单的数据填充、数据校验和格式化以及数据打包。另外,页面在加载完毕后往往需要执行一段初始化逻辑。本期将介绍decj对HTML表单的声明式增强和声明式页面/模块初始化这2个特性。


声明式表单功能增强


decj以声明式编程的方式对表单数据展现和收集功能进行增强。在数据展现方面,decj支持根据指定的数据自动将数据填充到表单中、对表单字段值进行自动格式化。在数据收集方面,decj支持对表单字段值进行自动校验、对表单数据自动打包提交。同时,decj支持对表单的Reset按钮的功能进行增强。


模块业务对象元数据


decj的表单增强功能依赖于模块的业务对象元数据。从MVC(Model-View-Control)设计模式的角度来看,表单本身属于View,其所展现和收集的数据属于Model。decj称呼每个Model的实例为一个业务对象(Business Object,简称BO)。一个页面中可以有多个表单,这些表单对应各自的业务对象。模块的业务对象元数据则用于描述一个模块所涉及的各个业务对象的信息,包括业务对象的名称、别名和类型。业务对象类型则描述了该类型的业务对象包含哪些字段以及每个字段的名称、别名、字段类型、数据校验规则以及格式化要求。


模块的业务对象元数据是一个普通Javascript对象,可以使用JSON进行声明。


上述JSON对象中,属性“bo”的值声明了模块使用了哪些BO,并声明了各个BO的名称、别名以及BO类型名。BO的别名默认为BO名称本身,它对应于表单的name属性值。每个BO类型的声明包含了若干个字段声明。


字段声明描述了每个字段的类型名称(stereoType)、字段别名(alias)、字段类型参数(typeParam)及数据校验规则(validation)。其中字段别名默认为字段名本身,它对应表单控件的name属性值。


假设某IT社交网站要实现一个会员信息编辑的功能,会员信息包括会员的姓名、性别、技能专长领域等。


模块业务对象元数据可以在Javascript代码中直接声明,也可以采用服务端代码生成。若采用服务代码生成,需要在模块定义中声明一个名为metaDataURL的属性,其值提供业务对象元数据的URL。如清单12所示:


清单 12. 在模块定义中声明业务对象元数据提供者的URL


metaDataURL:'handler.jsp?src=metaData.json'


MVC是被普通采用的设计模式。许多Web应用的服务端代码也是采用了MVC,因此我们可以利用服务端代码自动根据服务端代码中的业务对象生成模块的业务对象元数据。这样既可以减少代码编写量,又可以使客户端和服务端在Model层保持同步。比如,在Java平台中,开发人员可以使用Java的反射(Reflection)API及JSON API自动生成相关BO的元数据。


表单内容自动填充


Web应用经常需要将服务端的数据填充到表单中,以便对数据进行查看、编辑。该功能多数是通过服务端代码(如JSP)或者调用客户端封装好的代码来实现。decj框架则支持根据指定的业务对象元数据自动对表单进行内容填充,而无需开发人员编写代码调用任何API。


下面以上一节中提到的虚构的某IT社交网站的会员信息编辑功能为例,讲解decj的表单内容自动填充功能。在给定会员信息相应数据的情况下,要实现该表单的自动填充,开发人员只需要为decj提供好相关的业务对象元数据(如清单11所示),并编写好表单的HTML代码即可。


编写表单的HTML代码的时候,要注意表单元素的name属性值以及表单中各个控件的name属性值与表单所在模块的业务对象元数据中声明的业务对象别名、字段别名要分别相同。decj正是根据这种对应关系将业务数据显示到相应表单的对应控件上。


填充表单所需的业务对象数据,可以由服务端代码生成或者直接在Javascript代码中指定。


表单数据校验、数据格式化


decj框架可以根据业务对象元数据对自动填充的表单中的字段进行自动数据校验、格式化。开发人员无需编写任何代码(除非要进行扩展和定制)。


decj的表单数据校验分两种。一种基于业务对象元数据中声明的数据类型(stereoType属性),另一种基于业务对象元数据中声明的数据校验规则(validation属性)。前者可以根据字段的数据类型对其值进行校验。比如Number型的字段,当输入值包含非数字字符时,decj就会提示数据校验不通过。后者可以根据指定的规则名对应的校验规则对字段的输入值进行校验。比如,String型字段默认包含了一个名为“Size”的校验规则,该规则会指示decj对相应字段的值的长度进行校验。若字段值长度不符合要求,则decj会提示数据校验不通过。


说明名为“mgmtExpr”的字段其类型为数字型,其类型参数中声明了其数据格式化采用的Locale为“cn”(中国),小数点为2位。那么,当该字段的输入值包含无效的非数字字符时,decj就会提示数据校验未通过。


若“Management expierence“的字段值为”1032.56”,则decj的数据校验会通过,并且该字段值会被自动按照中国的数字格式化规则进行格式化。


开发人员也可对decj进行扩展和定制,建立自己的数据类型和数据校验规则、数据格式化。限于篇幅,本文不详述。

表单数据自动提交


越来越多Web应用开始支持JSON格式的数据,将表单的数据以JSON格式打包提交给服务端程序进行处理已经不稀奇。采用传统的编程方式,这需要编写代码来调用相关API实现。而采用decj,开发人员只需要提供模块的业务对象元数据即可实现自动将表单的数据以JSON格式提交到服务端。


decj默认会以JSON格式对表单数据进行打包。和传统的开发方式相同的是,要提交表单,开发人员需要设置表单的action属性(指定服务端接收程序的URL)以及在表单中添加submit按钮。


所不同的是,传统方式下表单提交数据时只能采用HTTP的POST或GET方法。而decj则支持以任何HTTP方法提交数据,包括PUT、POST、GET等。这使得decj开发的客户端代码可以访问REST(Representational State Transfer) Web服务。


decj默认采用POST方法提交表单数据。若要以其它HTTP方法提交表单数据,可以在模块定义中声明decj表单描述符(Form Descriptor)的method属性。表单描述符是decj模块的一个名为forms的属性。forms属性的值是一个普通Javascript对象,该对象的各个属性的名字与模块页面中的各个表单的name属性一一对应。


decj也支持以传统的URI-Encode格式(即以name/value对的方式编码表单各个字段)提交表单数据。若要以URI-Encode格式提交表单数据,开发人员需要将表单的描述符的encodingType属性值设置为“application/x-www-form-urlencoded”,或者给表单元素添加一个名为“_enctype”的自定义属性,设置其值为“application/x-www-form-urlencoded”。


声明式页面/模块初始化


许多页面、模块往往需要在页面、模块刚被加载完毕后执行一些初始化的代码。采用传统的编程方式,这需要我们侦听window对象的onload事件,然后在相应的事件监听器中编写初始化代码。采用这种方式,即便使用jQuery库,应用也需要调用jQuery的相关API。


采用decj框架,应用代码只需在模块定义中声明init属性即可,而无需调用任何API。init属性的值是一个函数,该函数会在当前模块被加载完毕后被执行。因此,页面、模块的初始化代码可以写在该函数内。


另外,decj中初始化代码被执行的时机与传统编程范式有些区别。传统的编程范式是通过侦听window对象的onload事件来执行初始化代码。而window的onload事件是在当前加载的页面及其引用的所有资源(包括CSS文件、Javascript文件和图片文件等)都被加载完毕才会被触发。而decj框架会在其加载完当前模块所需的Javascript文件、HTML文件(并将其内容附加到当前HTML DOM树上)以及国际化资源文件就执行初始化代码。并且,decj是以并行的方式加载模块所需的Javascript文件、HTML文件以及国际化资源文件的。因此,采用decj框架时,模块、页面的初始化代码可以更加早地被执行,从而提高了页面就绪的速度。


小结


本期介绍了decj的“声明式表单功能增强”及“声明式模块初始化”这几个特性如何解决Web前端开发中如下常规问题:

  • 表单的数据填充、数据打包提交、数据校验和格式化

  • 页面初始化逻辑

下一期将介绍如何以零编码的方式实现Web应用的国际化化支持。


注:原文较长,这儿为部分节选内容,请点击原文链接查看全文。


***********************************

本文来自InfoQ微信公众账号:infoqchina

1、回复“今日新闻”,查看今天更新的新闻;

2、回复“今日英文”,查看今天英文站的更新;

3、回复“文章 +关键词”,搜索关键词相关内容;

4、回复“QCon”,了解QCon大会相关信息;

5、回复“活动”,了解最近InfoQ组织的线下沙龙;

6、回复“架构师”,获取《架构师》下载地址;

7、回复“投稿”,了解投稿和加入编辑团队的流程。

***********************************

 
InfoQ 更多文章 Facebook如何实现PB级别数据库自动化备份 学术派Google软件工程师Matt Welsh谈移动开发趋势 Spotify为什么要使用一些“无聊”的技术? 妹纸们放假了,汉纸们做啥? 大多数重构可以避免
猜您喜欢 Android动画的使用(二) 最美应用-从 Android 研发工程师的角度 の 最美时光 苹果公司哪些岗位工资最高? 上海地区IC工程师月薪调查 硅谷科技巨头最刁钻面试题集锦。