• 1. Dorado7 Standard Edition 基础培训 v1.0
  • 2. 大纲Dorado7简介 项目的基本结构和配置 基本的界面开发技巧 Dorado7 JavaScript开发基础 基于数据模型的界面开发 典型控件及功能介绍 配置重用 Dorado7 Addon简介
  • 3. Dorado7简介
  • 4. 产品定位定位:展现中间件 两个核心价值 更好用的前端界面 更高的开发效率 适用范围 适合基于Browser/Server架构的管理类应用,不太适合面向互联网的开放式站点。 界面元素的风格 对搜索引擎的友好度 最适合采用ORM技术实现数据持久层的开发模式,同时也能适应基于JDBC的开发模式。
  • 5. 更好用的前端界面丰富的界面控件 支持各种主流浏览器 尚未完成低版本IE下的详尽测试 相比Dorado5更加Ajax化 更好的支持异步服务端通讯 JS、CSS的按需装载和Server端自动合并
  • 6. 更高的开发效率全新的基于Eclipse的IDE。 Dorado产品一贯的特色——以XML配置简化前端界面的定义。 * 尝试以XML替代传统JSP * 以数据模型为核心的开发模式。 数据敏感控件 立体数据模型 遵循"约定优于配置"的设计思想 自动方法适配
  • 7. 以XML替代传统JSP的原因基于管理类应用界面的特点,采用控件+布局管理器的界面定义模式最为高效。(如Swing、SWT等) 信息量大,对控件利用率的要求较高。 需很好的适应各种分辨率。 界面元素相对程式化。有利于简化界面开发过程和降低后期维护成本。 基于HTML的开发模式页面代码冗长且不易维护。 基于HTML的开发模式对开发者的要求较高,需时刻考虑HTML代码对各种浏览器的兼容性。 如有需要,开发者仍有多种方式回到基于HTML的开发模式下。
  • 8. 以数据模型为核心的开发模式UI控件发展的两个阶段 离散控件集型控件集——Dojo、Ext3 数据模型驱动型控件集——Dorado、Ext4 Ext的发展历程映证了数据模型驱动型控件集是更加高效的。 Dorado一贯主张将数据与表现形式分离。 数据载体——DataSet 数据感知控件——DataGrid、TextEditor、….
  • 9. 数据模型驱动型控件集的优点开发者日常接触的API的数量大大减少。 数据模型中提供了很多附加的功能,例如:状态管理、翻页、校验、提交等等。可以在很大程度上简化开发。 培养开发人员以更加贴近业务逻辑的角度思考问题。 始终把精力放在核心的业务逻辑的实现上,而不必因为各种零散的界面特效而致思维发散。 页面代码更加集中,所以更加容易阅读和维护。 大部分的页面代码会围绕数据模型展开。 当界面设计改变时,重构变得更加简单。 因为数据模型几乎不需要改变,开发者需要做的只是改用一些其他的数据感知控件。
  • 10. 项目的基本结构和配置
  • 11. web.xml和文件结构web.xml的两种配置方式(略) 当用户没有自行扩展Spring的ContextLoaderListener时的配置方法(默认) 。 当用户自行扩展了Spring的ContextLoaderListener时的配置方法。 doradoHome的位置 默认位于/WEB-INF/dorado-home 通过web.xml中的context-param来指定,参数名为doradoHome。 通过环境变量DORADO_HOME来指定
  • 12. 运行模式Dorado的运行模式及相应的配置装载规则 Production(生产环境) Debug(开发/调试) Test(测试) 自定的运行模式
  • 13. Spring上下文.properties和context.xml的作用和相互之间的关系。 运行时的Spring上下文 context和servlet-context之间的从属关系。 servlet-context通常只应放置SpringMVC的相关配置信息。ContextServlet-ContextParent
  • 14. 资源定位表达式的语法资源定位表达式通常用来描述一个或一组文件的位置。 基本格式: [协议:]路径 目前支持的协议: file: 表示操作系统的文件系统路径。 home: 表示子doradoHome所在位置起始的路径。 classpath: Java资源路径。 classpath*: Java资源路径,是特别为了从多个jar包中根据通配符批量的提取资源而提供的。 协议是可以省略的,当不指定具体的协议时Dorado7会自行判断应如何理解用户给出的路径。 如果路径以"/"开头,Dorado会认为该路径描述是项目web根下的文件。 如果路径不以"/"开头,Dorado按照classpath协议来处理路径。 如有需要开发人员可以自行扩展协议。
  • 15. 资源定位表达式的示例file:d:/workspace/test/foo.txt classpath:org/myproject/configure.xml 与 org/myproject/configure.xml 是等效的。 /WEB-INF/template.jsp file:d:/workspace/test/**/*.xml 所有d:/workspace/test目录(包括子文件夹)下的xml文件都会被该表达式命中。 classpath:models/*.xml或models/*.xml 所有classpath中models下的xml文件都会被该表达式命中。 classpath*:models/*.xml 所有jar包和classpath中models下的xml文件都会被该表达式命中。
  • 16. 几项基本配置的简介context.xml#dorado.dataConfigLoader 用于配置数据模型定义文件的存放规则。 context.xml#dorado.viewConfigFactoryRegister 主要用于配置URL与View配置文件之间的映射关系。
  • 17. 基本的界面开发技巧View配置文件的基本结构 实做HelloWorld EL表达式 控件的基础知识 布局管理器 实做Ajax 服务定位表达式 自动方法适配 HTML模板 对象监听器
  • 18. View配置文件的基本结构Arguments 用于定义参数,这种参数可在当前的View配置文件中通过EL表达式引用。 通过${argument.foo}的形式引用。 Context 用于定义视图上下文参数,这些参数的值会自动在该视图对应的Server端和Client端运行坏境中传递。 Server端通过context.get(DoradoContext.VIEW, "foo")读取。 Client端通过view.get("context.foo")读取。 Model 用于定义数据模型对象 View 用于定义视图的可见区域
  • 19. 实做HelloWorld
  • 20. EL表达式两种EL表达式 静态EL表达式:${expression} ,在创建目标对象的过程中一次性的求值。 动态EL表达式:$${expression},以动态代理的方式创建目标对象,并在外界每一次读取相应属性时进行求值。 基本语法 ${3x2} =6 ${3>2} =true ${empty(foo)} - empty()是内置的函数,用于判断传入参数是否为null或空字符串。 ${foo>0? "enabled":"disabled"} - 条件表达式。 ${foo["bar"]}或${foo.bar]} - 读取map中的bar键值。
  • 21. Dorado7提供的EL隐式变量与线程无关(任何配置文件中都可以使用) null - 表示null env - 用于获取系统环境变量。${env.JAVA_HOME}或${env["JAVA_HOME"]} system - Java的系统属性,即System.getProperties()对象。 configure - 用于获取Dorado7的配置信息。${configure["runMode"]} 与线程相关(通常仅在处理Http请求的线程中可以使用) argument - 用于获取当前配置文件中的参数值,仅可用于View.xml context - 当前线程中的DoradoContext。 ctx - 用于简化对DoradoContext的getAttribute方法的访问。${ctx["foo"]}相当于${context.getAttribute("foo")} util - 基本工具类,见com.bstek.dorado.core.el.ExpressionUtilsObject的javadoc。 request - 当前的HttpServletRequest对象。 req - 用于简化对request的getAttribute方法的访问。 ${req["foo"]}相当于${request.getAttribute("foo")} param - 用于简化对request的getParameter方法的访问。 ${param["foo"]}相当于${request.getParameter("foo")} session - 当前的HttpSession对象。 servletContext - 当前的SerlvetContext对象。 web - 基本工具类,见com.bstek.dorado.web.WebExpressionUtilsObject的javadoc。 如有需要,开发人员可以自行扩展出更多的隐式变量。
  • 22. 特殊EL隐式变量$${this}或$${this.foo} 此种隐式变量通常只用在DataType的Reference属性中。this表示当前正在处理的数据实体对象,即系统正在尝试获取该数据实体对象的Reference属性的值。 此种EL表达式的实际求值范围是在Client端的JavaScript环境中。
  • 23. 控件的基本类别基本类别 不可见控件 - DataSet、Action、FormProfile 可见控件 独立控件 - Button、TextEditor、Grid 容器控件 - Container、Panel、GroupBox 复合控件 - TabControl、SplitPanel、ToolBar 容器控件与复合控件的区别 最大的外在区别在于是否支持布局管理器。 容器控件中总是有一块空白的矩型区域用于显示隶属于容器的子控件,且子控件的显示方式受容器控件当前选用的布局管理器控制。 复合控件虽然也可以包含一到多个的子控件,但这些子控件如何被显示是由复合控件自身的逻辑决定的。
  • 24. 控件的其他分类方式浮动控件 默认不接受布局管理器的管理,且显示时浮动于所有非浮动控件之上。例如:Dialog、Menu、FloatContainer。 如果将浮动控件的floating属性设置为false,则浮动控件将失去浮动特性且将接受布局管理器的控制。 数据感知控件 可以与DataSet进行绑定用于显示、修改或控制DataSet中的数据的控件。例如:DataGrid、TextEditor、AutoForm。
  • 25. 布局管理器在默认不使用JSP的情况,需要灵活的掌握运用容器型控件和各种布局管理器来完成对界面的布局。 Dorado7目前提供的布局管理器: DockLayout 停靠式布局 AnchorLayout 锚定式布局 FormLayout 表单时布局 HBoxLayout 水平箱式布局 VBoxLayout 垂直箱式布局 NativeLayout (其实什么都不做的布局)
  • 26. DockLayout停靠式布局将控件分成5中区域:left、top、right、bottom和center。 每个控件选择一种区域由布局管理器按照顺序进行排列。 选择center区域的控件总是到最后才被放置,他总是占尽所有剩余的空间。 除center区域之外,其他4中区域都可以出现0到n个, center区域最多只能出现一次。 如果某控件没有显式的声明选择哪中区域,那么布局管理器会尝试按照center区域对其进行布局。
  • 27. AnchorLayout锚定式布局的基本思路是设定某控件的四周边框与容器边界或其他控件之间的锚定关系,以此来确定该控件实际所处的位置和尺寸。
  • 28. AnchorLayout - 场景1简单的边界锚定
  • 29. AnchorLayout - 场景2通过锚定关系来控制控件的尺寸 DockLayout其实只是AnchorLayout的一种特殊场景
  • 30. AnchorLayout - 场景3利用百分比锚定实现居中等效果
  • 31. FormLayout表单式布局首先把空间分成1到n列,然后由上往下依次排列各个子控件。 每个子控件可以选择自己要占用几行或几列。
  • 32. HBoxLayout和VBoxLayoutVBoxHBox
  • 33. 实做AjaxAjax调用的服务成为可暴露服务,即我们必须显式的声明一个服务是可以被Client端远程访问的,这是Ajax调用才能成功。 每个可暴露服务包含两个属性:名称、服务定位表达式。 @Expose标注自动在Dorado7的ExposedServiceManager中自动注册了一个可暴露服务。 以toUpperCase方法为例,自动注册的服务的名称为ajax#toUpperCase,其对应的服务定位表达式为spring:ajax#toUpperCase 如果要手工的声明一个可暴露服务,需要在spring配置中添加一段:
  • 34. 服务定位表达式服务定位表达式用来描述服务的查找方式,即Dorado7通过服务定位表达式来查找到具体服务,以便于对服务进行调用。 基本格式: 协议:服务名[#方法名] 这里的服务名通常是代表一个JavaBean。 目前支持的协议: spring: 表示其后的服务名是某个Spring上下文中的Bean的id。 classpath: 表示其后的服务名一个类的完全限定名,当Dorado7需要调用此服务时会自动按照单例模式来实例化该类。(此种方式不推荐使用,因为Spring是Dorado7的标配,将服务注册在Spring上下文中可以获得很多额外的好处)
  • 35. 自动方法适配基于"约定优于配置"的设计思路而提供。 好处: 几乎不需要引入任何Dorado7的API。 按照业务的需要而不是Dorado7的需要来为表现层编写代码。 可以令Dorado7与后台业务逻辑之间的粘合层代码更加简洁、易读。
  • 36. 适配规则适配算法: 按照参数名进行适配 即Dorado根据参数名来确定每个参数的作用。 相对严谨的适配规则,但有时使不够业务化。例如对于AjaxAction的后端方法,其参数名必须为parameter。 按照参数类型进行适配 即Dorado根据参数类型来确定每个参数的作用。 当参数较为复杂时Dorado可能无法准确的判断个参数的作用。 混合式的适配规则(尚未提供) 即现根据名称规则进行一次适配,对于那些无法匹配的参数继续尝试通过类型规则进行适配。 自动方法适配不会强行调用目标方法 当其认为适配可能存在歧义时会报错而不会继续执行方法调用。 对于Map类的参数自动方法适配会尝试将其拆解,用其中的键值对与方法参数进行适配。 可自动注入的参数: (TODO) methodInvocation context request
  • 37. HTML模板Velocity页面模板示例 资源文件的约定:与View同名的html、js、css文件可以被自动装载。 3种render模式 renderTo模式 renderOn模式 renderOn容器模式 JSP页面模板示例 使用极少的Taglib,有利于与网页设计师、美工的协同工作。 执行顺序与Dorado5相反。 可以支持JSP之外的其他页面模板技术。
  • 38. 对象监听器onInit监听和beforeInit监听 了解ViewConfig和View View监听器中的控件自动注入 全局对象拦截器 更多的细节见 http://wiki.bsdn.org/x/m4A0
  • 39. onInit监听和beforeInit监听Dorado中绝大多数的可配置对象都listener属性,可以定义一到多个监听器用以监听对象的创建过程。 定义监听器时可以使用自动方法适配。 在监听一个对象时可以选择在对象被初始化之前还在初始化之后触发。 即beforeInit和onInit两种监听方式。 一个监听器究竟使用哪一种监听方式,取决于该方法的方法名中是否使用before前缀,例如beforeInit。
  • 40. 了解ViewConfig和ViewViewConfig和View之间关系和区别 View对象特指可视部分,通常只在页面打开的请求中被创建。 ViewConfig对象在客户端调用Ajax请求时(包括装载数据、提交数据等)也会被创建。 从隶属关系的角度来看View是ViewConfig中的一个子对象。ViewConfig在实例化的过程中未必会实例化其中的View。
  • 41. View监听器中的控件自动注入View的拦截提供了额外的子控件自动注入功能。 比较笨拙的写法: public void onInit(View view) { Button buttonOK = (Button) view.getComponent("buttonOK"); buttonOK.setDisabled(true); Panel panelMain = (Panel) view.getComponent("panelMain"); panelMain.setCollapsed(true); } 比较灵巧的写法(利用子控件自动注入) public void onInit(Button buttonOK, Panel panelMain) { buttonOK.setDisabled(true); panelMain.setCollapsed(true); }
  • 42. 全局对象监听器可以在Dorado7配置全局的对象监听器,监听所有对象的创建过程。 可以利用通配表达式批量的监听一部分对象。 可以利用泛型监听某一个特定类型的对象。 下面的类可以监听系统中所有View的创建过程。 public class ViewInterceptor extends GenericObjectListener { @Override public boolean beforeInit(View view) throws Exception { // your code } @Override public void onInit(View view) throws Exception { // your code } }
  • 43. Dorado7 JavaScript开发基础JavaScript基础 JSON 闭包 回调函数 虚拟面向对象 虚拟属性——Attribute 事件——Event 创建Dorado7对象 常用技巧和API
  • 44. JavaScript基础—— JSON 1JSON相当于Java世界里的POJO(由List和Map组成的POJO) 基本语法: var d = { prop1:"value", prop2:true }; 相当于 var d = new Object(); // 也可以写作 var d = {}; d.prop1 = "value"; d.prop2 = true; JS中的Object比较像Java的Map,可以给任意属性赋值。
  • 45. JavaScript基础—— JSON 2{ name: "Phone", propertyDefs: [ { name: "product", label: "型号", required: true }, { name: "manufacturer", label: "生产商" }, { name: "type", label: "机型", mapValues: [ { key: "A", value: "直板" }, { key: "B", value: "翻盖" }, { key: "C", value: "滑盖" }, { key: "D", value: "旋盖" }, { key: "Z", value: "其它" } ] }, { name: "price", label: "价格", dataType: "float" } ] }
  • 46. JavaScript基础——闭包关于闭包的定义非常晦涩难懂,因此我们通过下面的例子简单的介绍闭包 function a() { var text = "Hello!" function b() { alert(text); } setTimeout(b, 500); } 此处的function b就是一个闭包函数。 闭包可以访问其代码块所处环境中的局部变量。 当一个局部变量被闭包引用时,JS引擎会阻止该局部变量被GC回收。
  • 47. JavaScript基础——回调函数回调函数最常见于Ajax操作和延时操作(如前面的例子)。 通常都是利用闭包完成的。 示例: $ajax.request("data/phones.js", function(result) { grid.set("items", result.getJsonData()); }); 如果是同步操作,代码往往是如下形式的: var result = $ajax.requestSync("data/phones.js"); grid.set("items", result.getJsonData());
  • 48. 虚拟面向对象JavaScript本身并不支持面向对象,但是可以利用其Prototype去模拟部分面向对象语言的特征。 此处的虚拟面向对象即指Dorado7提供的JavaScript模拟面向对象编程。 这里我们只介绍Dorado JS 对象的使用和相关约定,而忽略对象的声明、扩展等内容。
  • 49. 虚拟面向对象——虚拟属性Dorado JS对象的绝大部分属性都是通过get和set方法进行读写操作的。 var v = editor.get("value"); button.set("caption", "OK"); set方法支持批量属性设置。 button.set({ icon: "images/ok.gif", caption: "OK", onClick: function() { alert("You clicked OK."); } }); get和set方法都支持迭代式操作。 oop.get("address.postCode"); oop.set("address.postCode", "7232-00124"); get和set方法的迭代操作为自动处理迭代过程中遇到的Dorado JS对象或普通JSON对象。
  • 50. 虚拟面向对象——事件1一个事件下可添加多个监听函数,可使用下面的两种方法。 button1.set("onClick", function(self) { // 此方法只能定义一个监听函数 }); 或 button1.addListener("onClick", function(self) { //此方法可以为一个事件添加多个监听函数 }); Dorado7中所有的事件都只支持self和arg这两个事件参数。 self总是激发事件的对象自身。 arg的类型与具体的事件类型有关,很多情况下是一个JSON对象,其中可能包含有非常丰富的传入信息。 几乎所有事件中的this均指向的是该控件隶属的View对象,View对象的onCreate事件中的this是指向其自身的。 onCreate事件中的this是个例外,因为控件总是先被创建然后才被添加到控件树上,因此在onCreate事件被触发时控件并不知道其隶属的View对象。所以onCreate事件中的this并不指向最终的View。 所有事件的返回值类型都是逻辑型,用于通知系统是否继续触发同一事件的后续监听器。不返回任何值则系统按true来处理。
  • 51. 虚拟面向对象——事件2很多beforeXXX事件的arg参数中都支持一个名为processDefault的可写属性,用于通知系统是否要执行该事件所代表的后续操作。 employeeDataType.addListener("beforeRemove", function(self, arg) { if (arg.entity.get("married")) { dorado.MessageBox.alert("已婚的员工不能被删除!"); arg.processDefault = false; } }); 抛出一个异常,同样可以达到类似的目的。 employeeDataType.addListener("beforeRemove", function(self, arg) { if (arg.entity.get("married")) { throw new dorado.Exception("已婚的员工不能被删除!"); } }); 两种方法其实有区别,可能导致不同的结果!
  • 52. 如何创建Dorado7对象大部分Dorado JS对象的构造参数都是一个用于初始化新对象的JSON对象。 此构造参数等价于传递给set方法的批量写入模式的参数。 new dorado.widget.Button({ caption: "Say Hello", onClick: function(self, arg) { dorado.MessageBox.alert("Hello!"); } })
  • 53. 创建Dorado7对象——$type在作为构造参数的JSON对象,可以利用$type属性来简化子控件的声明过程。依次类推,你甚至可以用一个JSON对象将整个Dorado7的视图全部声明好 例如下面的代码也可以用来创建一个Button。 { $type: "Button", caption: "Say Hello", onClick: function(self, arg) { dorado.MessageBox.alert("Hello!"); } } 在jsodc中可以找到所有对象对应的$type。 当一个带创建的对象不需要传入构造参数时,甚至可以根据一个代表$type的字符串来创建相应的Dorado对象。
  • 54. 创建Dorado7对象——示例new dorado.widget.Grid({ columns: [ "#", // 相当于dorado.wdiget.grid.RowNumColumn,RowNumColumn的$type是# { property: "product" }, { $type: "Group", caption: "Volumn", columns: [ { property: "length", width: 50 }, { property: "width", width: 50 }, { property: "height", width: 50 } ] }, { property: "price", onRenderCell: function(self, arg) { arg.cell.style.color = (arg.data < 100) ? "red":""; } }, ] });
  • 55. 常用技巧和API(1)通过控件ID获得控件的方法。以buttonOK,this在大部分事件中指向当前View。 this.get("#buttonOK") 今后推荐的方法,原因是当你需要进一步操作buttonOK时会非常方便。例如this.get("#buttonOK.caption")可以直接获得Button的caption属性。 this.id("buttonOK") 今后不再推荐。 掌握对象的tags属性。 Dorado允许开发人员为对象定义一到多个的标签,然后利用标签批量的获得一组对象以便于对他们进行统一的操作。 根据标签获得一批对象的方法包括: this.get("^foo") 今后推荐的方法。例如:this.set("^foo.disabled", true) this.tag("foo") 今后不再推荐。
  • 56. 常用技巧和API(2)View的get和set中更多使用技巧 this.get("title") - 读取View自身的属性 this.get("#buttonOK") this.get("^foo") this.get("@DataTypeProduct") - 根据名称获得某个DataType $url() - 用于转换URL ">images/icon.gif"将转换为"/appContextPath/images/icon.gif" "skin>widget.css"将转换为Dorado当前当前皮肤路径下的widget.css的URL。因为skin是预设的URL前缀代表当前皮肤的跟路径。 今后将会开放用户自定义URL前缀。
  • 57. 常用技巧和API(3)$DomUtils.xCreate() - 根据以JSON形式定义的组件的模板信息快速的创建DOM元素 $DomUtils.xCreate({ tagName: "button", content: "Click Me",// 定义按钮的标题 style: {// 定义按钮的style border: "1px black solid", backgroundColor: "white" }, onclick: function() {// 定义onclick事件 alert("Button clicked."); } }); $log() - 记录调试日志。日志结果可在页面上按F2后看到。
  • 58. 常用技巧和API(4).each() - Dorado7扩展了标准的Array使之可支持each迭代,除Array之外Dorado7提供的EntityList、KeyedList等集合特性的对象也支持each迭代。 var s = ''; ['A', 'B', 'C'].each(function(item) { s += item; }); // 最终结果为s == "ABC"
  • 59. 常用技巧和API(5)使用偏移量来定义图标 例如按钮的icon属性中支持这样的值——url(skin>common/icons.gif) -140px -20px
  • 60. 基于数据模型的界面开发立体数据模型 实做单表CRUD界面的开发 DataProvider和DataResolver DataType 实做主从表维护界面 DataPath 实做数据树维护界面 数据操作常用技巧
  • 61. 立体数据模型 立体数据模型是Dorado7中全新的、最为核心的概念。 什么叫立体数据模型? 为什么需要引入立体数据模型? 怎么实现立体数据模型?
  • 62. Web应用中数据处理的过程Web应用的运行过程就是对数据进行处理的过程。
  • 63. 平面数据和立体数据我们以平面数据和立体数据来概括数据在前述过程中的两种数据载体形式。 概念 平面数据:通过键值来表达数据与数据间的关系。例如关系型数据库中的数据。 立体数据:通过引用来表达数据与数据间的关系。例如通过Hibernate获得的领域模型数据。
  • 64. 以数据载体形式的角度再度观察其中的立体数据被标以蓝色
  • 65. 对数据形式进行一些归纳数据的本质是立体的。 数据库中的数据是平面的。 ORM把数据库中的平面数据映射成立体的。 XML、JSON数据可以方便的描述较简单立体数据。 网页Form中的数据是平面的。 在进行运算时,处理立体数据比处理平面数据容易。 Dorado5的Dataset是平面的。
  • 66. 为什么要提出立体数据模型由于数据的本质是立体的,因此当界面越能展现和处理这种立体关系时,它对用户友好程度就越高。 Hibernate(ORM)的使用经验告诉我们,平面数据和立体数据进行互转时需要付出很大的代价。 综合以上两点,我们需要在Client端提供立体数据模型以提高界面的友好度、同时改善应用数据处理过程的流畅性。
  • 67. 5与7在数据处理方面的主要区别
  • 68. 怎样实现立体数据模型? 首先进一步了解两个概念: 数据载体 用于封装和承载数据的对象,通常由数据实体和数据实体集合这两种对象构成。 数据实体是指一个拥有一到n个属性的对象。在Java中通常表现为POJO Bean或Map;在Javascript中通常表现为JSON对象。 数据实体集合用于管理0到N个相似的数据实体。在Java中通常表现为List/Set;在Javascript中通常表现为Array。 数据集 数据集是指那些根据业务逻辑或编程的需要提取出来的一堆数据。 一个数据集的所有数据往往在逻辑上具有很强的相关性。比如当我们开发一个部门信息的维护界面时,会提取出某部门及其中所有雇员的信息作为一个数据集。
  • 69. Dorado7中的数据载体Dorado7在Server端不提供专用的数据载体对象,而是直接使用POJO Bean/Map以及List/Set来作为数据载体。 事实上,处于状态管理等需要Dorado7会动态代理(Cglib或Javassist)对原始的数据载体进行一个功能增强,只是大多数情况下开发员不需要也不会注意到这一点。 这一做法可以在很大程度上简化Dorado7与用户的业务逻辑层对接的难度。 Dorado7在Client端提供了专用的数据载体Entity/EntityList,他们的用法非常类似于JSON/Array。同时,Dorado7也支持直接以普通的JSON/Array最为数据载体。 之所以要在Client端提供了专用的数据载体,是因为Dorado7需要为数据载体添加很多诸如异步数据装载、状态管理、翻页、管理当前记录、数据校验等功能。
  • 70. Dorado7的数据集——DataSetDataSet主要的生命周期在Client端。 DataSet的功能相对于之前的版本被极大的弱化了。 其最重要的用途就是为其管理那堆数据赋予一个ID,以便于数据感知控件能够找到这些数据。 DataSet不再局限于二维表结构数据,而是可以支持非常自由的数据形式。 数据实体的集合 单个的数据实体 数据实体构成的树状结构 甚至是一个简单的字符串
  • 71. 一个稍复杂的数据集场景想象如下这样一个人事组织架构的场景。 在Dorado5中无论通过1个还是多个Dataset不无法实现这样的数据模型。 而Dorado7用一个DataSet就实现了。
  • 72. 立体数据模型带来的新问题如何对模型中的数据实体进行进一步的描述?例如定义各个属性的校验规则、数据类型、显示格式等等。 引入全新的概念——DataType 如何实现与数据感知控件的绑定? 引入全新的概念——DataPath 如何对管理当前记录? 立体数据模型的每一个集合都需要管理各自的当前记录。
  • 73. 实做单表CRUD界面的开发初步接触一系列对象 DataSet - 数据集 DataType - 数据类型(通常用于描述以数据实体及其中各个属性) DataProvider - 用于为Dorado提供数据(即将业务逻辑层中的数据导入到Dorado中) DataResolver - 与DataProvider的作用相反,用于将Dorado中的数据交还给业务逻辑层。
  • 74. 四种对象在数据环路中的作用
  • 75. 用数据库来打个比方
  • 76. DataType(1)DataType用来描述所有的数据类型,既包括String、int这样的简单类型,也包括数据实体这样的复杂类型。 DataType分为以下3类 简单DataType,如String、int、Boolean、Date 聚合DataType,如List、Set、Array 实体DataType,如POJO Bean、Map 由于Dorado默认已经声明好了常用的简单类型和聚合类型。因此绝大多数情况下,开发需要声明的只是业务系统中的数据实体类型。
  • 77. DataType(2)DataType还可以分为全局和私有两种。全局DataType必须定义在.model.xml文件中;而私有DataType声明在每一个.view.xml。 DataType支持继承(包括多重继承,即同时继承多个DataType) 在View引用DataType时,Dorado首先根据名称查找是否存在匹配的私有DataType,如果没有再继续查找全局DataType。 [Employee] - 表示以集合的方式引用一个名为Employee的DataType。 List[Employee]、Set[Employee]等也是合法的用法且代表了更多的含义,但是在绝大多数情况下我们都不需要这样使用。
  • 78. @DataProvider和@DataResolver与之前提到的@Expose相似,@DataProvider和@DataResolver会动将当前方法对应的服务,根据一系列约定的规则,在运行时注册成全局的DataProvider和DataResolver。 DataProvider和DataResolver并不是简单的表示某个具体的方法。而且两种Dorado7中特有的对象。 如果需要手工的定义DataProvider或DataResolver。也可以直接利用IDE在.model.xml文件或当前.view.xml的Model节点下定义。
  • 79. 实做主从表维护界面
  • 80. DataPath用于描述如何提取、挖掘数据的表达式。其作用比较类似于XML中所使用的XPath。 基本语法: 属性名1(参数1,参数2,..)[逻辑表达式1,逻辑表达式2,..].属性名2(参数1,..)[逻辑表达式1,..].. DataPath支持用户为其扩展语法——自定义片段。 详见 http://wiki.bsdn.org/x/HgAL
  • 81. DataPath的一些示例(1)null(即空) - 相当于直接返回被查询的数据。 * - 同上。 [#current] -表示顶层集合中的当前Department。 # - 同上。 [#dirty] - 表示顶层集合中所有在客户端被改变过的(包含被删除的)Department。 #.employees - 表示顶层集合中当前Department中所有的Employee。 #.#employees - 表示顶层集合中当前Department中的当前Employee。
  • 82. DataPath的一些示例(2)departments(repeat) - 表示所有Department的集合。 .departments(R) - 表示除顶层Department外所有其它Department的集合。 #departments(R) - 表示各层当前Department的集合。 #departments(leaf) - 表示最末端的当前Department。即通过不断的尝试获取当前Department中的当前Department,直到最末端那个Department。 departments(R).employees[@.get("salary")>5000 && @.get("sex")=="male"] - 表示所有Department中的薪水高于5000的男性Employee。 departments(R).employees.id - 表示返回所有Employee对象的id属性值的集合。
  • 83. 实做数据树维护界面
  • 84. 数据操作常用技巧——Server端EntityUtils工具类 toEntity() EntityUtils.getIterable() 虚拟实体属性 EntityWrapper
  • 85. 数据操作常用技巧——Client端dorado.Entity createBrother() createChild() getMessages() remove() dorado.EntityList each() iterator() insert() remove() DataSet.getData和DataSet.queryData getData默认只返回DataPath命中的第一笔数据,可能是Entity,也可能是EntityList。 queryData返回DataPath完整的执行结果,且默认只返回Entity(只在使用#等确定只可能有最多一个命中数据实体的DataPath时)或Entity的数组。
  • 86. 典型控件及功能介绍CardBook Dialog SubViewHolder * Form相关控件 * Trigger HtmlContainer
  • 87. Form相关控件Dorado7为表单的开发在两个维度上提供了多种抽象。
  • 88. Form相关控件——FormElementFormElement通常由文本标签+编辑器+提示信息区组成,FormElement可以直接和DataSet进行绑定。 通过属性设置可以改变各个区域的大小和排列方式。 文本标签和提示信息区可以根据需要隐藏。 编辑器去提供了几种TextEditor、TextArea、CheckBox、RadioGroup等常用的编辑器,同时也允许用户将任意的其他控件放置在编辑器区。 如果用户自行在编辑器区放入的控件继承自AbstractEditor,那么FormElement会自动的维护其绑定属性。
  • 89. Form相关元素——AutoFormAutoForm可以看作是FormElement的集合。 AutoForm内部使用了FormLayout来进行布局。 AutoForm中除了可以添加FormElement之外,也可以添加任意Dorado控件。 AutoForm不再提供类似Dorado5的Group功能。
  • 90. Form相关控件——FormProfileFormProfile与FormElement、AutoForm相比是另一个维度上的抽象。主要用于对多个FormElement和AutoForm进行统一管理。 FormElement和AutoForm都具有formProfile属性,可以和一个FormProfile进行绑定,以便于接受FormProfile的统一管理。 在缺省情况下,FormElement、AutoForm会直接去寻找当前View是否存在一个id为defaultFormProfile的FormProfile,如果找到则自动与之进行绑定。所以通常我们并不需要手工的去建立FormProfile的绑定关系。
  • 91. Form相关控件——数据实体绑定Editor、FormElement除了支持标准的DataSet数据绑定之外,也支持另一中绑定——数据实体绑定。 数据实体绑定是指直接跟一个JSON对象或dorado.Entity对象进行绑定。 数据实体绑定是单向的数据绑定。Editor、FormElement之外绑定关系建立时自动显示出数据实体中相应属性的值,之后不再响应数据实体的变化。但每当编辑器中的值被用户改变时,这个变化都会自动更新到数据实体中。 在不使用DataSet数据绑定,且没有为AutoForm、FormProfile手工的设置数据实体(即entity属性)时, AutoForm、FormProfile会自动创建一个空的数据实体( JSON对象),并将其管理的编辑器与该数据实体进行绑定。 例如,我们直接创建一个AutoForm,并在其中添加若干个FormElement,并在运行时在AutoForm的个编辑器中输入一些内容。当我们通过AutoForm.get("entity")获得一个JSON对象时,改JSON对象中将包含我们刚刚输入的所有内容。
  • 92. TriggerTrigger表示文本编辑框右侧的快捷按钮 DropDown是Trigger的一种特例,特指各种下拉框。 每个文本编辑框可以绑定1到n的Trigger,用户可以为每个Trigger定义自己的图标。 介绍AutoMapDropDown 介绍CustomDropDown
  • 93. HtmlContainercontent属性 即支持HTML,也支持JSON方式定义的HTML(见DomUtils.xCreate()) JSON方式目前仅支持在运行时通过JavaScript API设置。近期将支持直接在IDE的属性栏中填写。(讨论${JavaScript}) contentFile属性
  • 94. 其他控件使用技巧hideMode - 控件的隐藏方式,有visibility/display两种选项。 利用Action的hotkey定义快捷键操作。 拖拽功能。
  • 95. 配置重用SubViewHolder * 配置信息的导入和导出 * 视图模板 * 组装控件
  • 96. 配置信息的导入和导出指从任意的.view.xml中导入一段配置信息到当前的view配置中。 Import - 即可以根据id导入源文件中的一段配置。该id既可能代表的某个控件,也可能代表某个Group。 GroupStart、GroupEnd - 用于定义一个组,该组中的内容可能被用于其他View引用,也可能用于视图模板功能。
  • 97. 视图模板相比配置信息的导入和导出,视图模板功能提供更高层次的抽象。并且也更加有利于从项目管理的角度来规范系统中所有的页面。 视图模板功能支持多重继承和参数。
  • 98. 组装控件配置型组装控件 完全利用现有的控件(包含其他组装控件)拼装而成的新控件。 支持虚拟属性。 未来提供虚拟事件。 如何注册配置型组装控件? 对象型组装控件 通过代码来动态的组装现有的控件(包含其他组装控件)拼装而成的新控件。 如何注册对象型组装控件?
  • 99. Dorado7 Addon简介Dorado Addon是指Dorado7的各种扩展包,通常是jar的形式提供的。 事实上在Dorado7标准版提供的jar包中,除dorado-core,其他都可以视为Dorado Addon。 Dorado Addon即可以提供新的控件、也可以提供新的皮肤、甚至是一整套完整的应用。
  • 100. Dorado7 Addon的基本结构dorado-package.properties client资源 resources scripts skins packages-config.xml