Dorado5页面刷新的原理就是图2.1"Dorado 5原理图"当中的5、6、7是一个向下的箭头,而没有向上的箭头,也就是说在5中ViewModel把Dataset的属性和数据集组装成XML数据给DoradoServlet,然后DoradoServlet通过HttpResponse的方式把XML数据和JavaScrpt输出到页面;Brich Engine把页面的XML数据和JavaScrpt初始化客户端Dataset。
我们通过2.1中的例子再来看看Dorado5页面刷新是怎样的一个过程:
- 根据JSP的处理过程,一开始是先解析Jsp文件,这个时候开始解析chapter2/sample2_1.jsp(代码 2.3:JSP页面代码)。
当JSP解析到<d:View>的时候,Dorado5会根据这个标签的配置在Request里创建ViewModel实例。sample2_1.jsp中<d:View>配置的config是com.bstek.dorado5.docent.chapter2.sample2_1.view.xml,其中里面定义了clazz为com.bstek.dorado5.docent.chapter2.Sample2_1ViewModel,所以这个时候Dorado5创建了Sample2_1ViewModel实例。Sample2_1ViewModel实例会根据自身的一些初始化方法和解析sample2_1.view.xml来初始化自身和创建所有Dataset和Control,Dataset和Control也会根据Sample2_1ViewModel里的一些初始化方法和解析sample2_1.view.xml来初始化自身。如Dataset设置了autoLoadData为true(默认值为true),Dataset会执行dataset.load()方法来取到外部数据。初始化完后<d:View>跟根据Dorado5的Setting和Sample2_1ViewModel的内容来输出Dorado5所需要的一些文件和属性默认值等。
<link rel="stylesheet" type="text/css" href="/Dorado5_2.1/dorado/smartweb2.loadStyleSheet.d?skin=default"></link> <script language="javascript" src="/Dorado5_2.1/dorado/smartweb2.loadFile.d?file=/skins/default/preferences.js"></script> <script language="javascript"> var __startTime=new Date();</script> <script language="javascript" src="/Dorado5_2.1/dorado/smartweb2.loadConst.d?language=cn&country=ZH"></script> <script language="javascript" src="/Dorado5_2.1/dorado/smartweb2.loadRes.d?res=/utils.js"></script> <script language="javascript" src="/Dorado5_2.1/dorado/smartweb2.loadRes.d?res=/base.js"></script> <script language="javascript" src="/Dorado5_2.1/dorado/smartweb2.loadRes.d?res=/control.js"></script> <script language="javascript"> var __DORADO_VERSION="5.2 080505.1206 (Unregistered)";var __DEFAULT_LOADDATA_SERVICE="/dorado/smartweb2.RPC.d";var __DEFAULT_UPDATEDATA_SERVICE="/dorado/smartweb2.RPC.d";var __DEFAULT_RPC_SERVICE="/dorado/smartweb2.RPC.d";var __CLIENT_DEBUG=true;var __DEFAULT_ONVALUE="1";var __DEFAULT_OFFVALUE="0";var __DEFAULT_INT_FORMAT="#";var __DEFAULT_FLOAT_FORMAT="#,###.##";var __DEFAULT_ANIMATED=true;var __CONTEXT_PATH="/Dorado5_2.1";var __SKIN_PATH="/Dorado5_2.1/dorado/smartweb2.loadFile.d?file=/skins/default";</script> <script language="javascript"> var __t=new ViewModel(null, "com.bstek.dorado5.docent.chapter2.sample2_1~com.bstek.dorado5.docent.chapter2.Sample2_1ViewModel"); $$e(__t, "onLoad", function (viewModel) { } ); function function1(p1, p2) { var test; } </script>
代码 2.6:<d:View>输出的html内容
JSP再往下解析,解析到<d:AutoForm/>等这些控件标签的时候,Dorado5会根据id查找Sample2_1ViewModel的contols存不存在,如不存在就在ViewModel里创建AutoForm,然后通过Contol.init()来读取view.xml的配置来初始化AutoForm;当在ViewMolde存在AutoForm控件之后,<d:AutoForm/>通过HttpResponse把AutoForm在页面展现的Html输出到页面。
<TABLE id="formForm" class="AutoForm" _doradoClass="AutoForm" cellspacing="0" cellpadding="0" border="0" style="width:100%;"><CAPTION style="display: none"> </CAPTION><TR><TD><TABLE width="100%" height="100%" cellspacing="0" cellpadding="0" border="0" style="table-layout: fixed"><TR><TD valign="top" ><FIELDSET id="formForm_group0" ><LEGEND></LEGEND><DIV><DIV class="GroupBoxDiv" style="width:100%;height:100%"><TABLE class="InnerTable" width="100%" cellspacing="0" cellpadding="4" border="0" style="table-layout:fixed;"> <COLGROUP> <COL width="100" ></COL> <COL width="50%" ></COL> <COL width="100" ></COL> <COL width="50%" ></COL> </COLGROUP> <TR><TD class="InnerTableLabelCell" align="right" >员工编号</TD><TD class="InnerTableContentCell" ><input type="text" id="formForm_editor_EMPLOYEE_ID" name="EMPLOYEE_ID" style="width:100%;"></TD><TD class="InnerTableLabelCell" align="right" >部门</TD><TD class="InnerTableContentCell" ><input type="text" id="formForm_editor_DEPT_ID" name="DEPT_ID" style="width:100%;"></TD></TR> <TR><TD class="InnerTableContentCell" colSpan="4" align="center" ><button id="buttonQuery" style="width:80;"></button></TD></TR> </TABLE></DIV></DIV></FIELDSET></TD></TR> </TABLE></TD></TR> </TABLE>
代码 2.7:<d:AutoForm/>输出的html内容
3当中的布局通过Html或者Dorado5的Layout布局器来进行布局。
<table border="0"> <tr valign="top"> <td><d:AutoForm id="formForm" /></td> </tr> <tr valign="top"> <td> <d:Layout type="hflow"> <d:Pane> <d:Button id="buttonSave" /> </d:Pane> <d:Pane align="right"> <d:DataPilot id="datapilotCustom" /> </d:Pane> </d:Layout> </td> </tr> <tr valign="top"> <td><d:DataTable id="tableCustom" /></td> </tr> </table>
代码 2.7:Dorado5页面布局
最后解析</d:View>的时候,ViewModel会把Datasets的数据和定义以及属性设置输出到页面,同时ViewModel根据页面的控件标签来输出Controls的定义以及属性设置输出到页面。这些Datasets和Controls的输出顺序是由规定的,根据不同的情况来决定输出的顺序。
<div style="display: none"><xml id="__datasetForm" > <rs possibleCount="0" pageCount="1" loadedPages="1"> </rs> </xml></div> <script language="javascript"> var datasetForm=$$c("Dataset", null, "datasetForm", "form");var _t=datasetForm;t.setPageSize(100);t.setInsertOnEmpty(true);var __f=t.addField("EMPLOYEE_ID",0);f.setLabel("\u5458\u5DE5\u7F16\u53F7");var __f=t.addField("DEPT_ID",0);_f.setLabel("\u90E8\u95E8");</script> <div style="display: none"><xml id="__datasetCustom" > <rs possibleCount="0" pageCount="1" loadedPages="1"> <r id="3" pageIndex="1" isCurrent="true" state="none" > <new>Default,Default,,,</new> </r> <r id="4" pageIndex="1" state="none" > <new>Default2,Default2,,,</new> </r> </rs> </xml></div> <script language="javascript"> var datasetCustom=$$c("Dataset", null, "datasetCustom", "Custom");var _t=datasetCustom;t.setPageSize(100);var __f=t.addField("EMPLOYEE_ID",0);f.setLabel("\u5458\u5DE5\u7F16\u53F7");var __f=t.addField("DEPT_ID",0);f.setLabel("\u90E8\u95E8");var __f=t.addField("EMPLOYEE_NAME",0);f.setLabel("\u5458\u5DE5\u59D3\u540D");var __f=t.addField("SEX",9);f.setLabel("\u6027\u522B");var __f=t.addField("BIRTHDAY",10);f.setLabel("\u51FA\u751F\u65E5\u671F");var __t=t.parameters();t.addParameter("EMPLOYEE_ID",0).setValue("");_t.addParameter("DEPT_ID",0).setValue("");</script> <script language="javascript"> var commandForm=$$c("QueryCommand", null, "commandForm");var _t=commandForm;t.setConditionDataset("datasetForm");_t.setQueryDataset("datasetCustom");</script> <script language="javascript"> var commandSave=$$c("UpdateCommand", null, "commandSave");var _t=commandSave;t.setMethod("save");var __f=_t.addDatasetInfo("datasetCustom", "all-change");</script> <script language="javascript"> var _downloadTime=new Date();var __t=$$c("GroupBox", null, "formForm_group0");_t.setTitle("\u67E5\u8BE2\u6761\u4EF6"); __t._initChildren=function(){ var _t=$$c("TextEditor", null, "formForm_editor_EMPLOYEE_ID", null, "text");t.setDataset("datasetForm");t.setField("EMPLOYEE_ID");var __t=$$c("TextEditor", null, "formForm_editor_DEPT_ID", null, "text");t.setDataset("datasetForm");t.setField("DEPT_ID");var __t=$$c("Button", null, "buttonQuery");t.setValue("\u67E5\u8BE2");_t.setCommand("commandForm");} var _t=$$c("Button", null, "buttonSave");t.setValue("\u63D0\u4EA4");t.setCommand("commandSave");var __t=$$c("DataPilot", null, "datapilotCustom");t.setDataset("datasetCustom");t.setButtonNames("movefirst,moveprev,movenext,movelast,appendrecord,deleterecord,postrecord,cancelrecord");var __t=$$c("DataTable", null, "tableCustom");t.setDataset("datasetCustom");t.setHeaderHeight(20);t.setRowHeight(19);t.setFooterHeight(20);var __t1=t.addColumn("EMPLOYEE_ID");t1.setField("EMPLOYEE_ID");var __t1=t.addColumn("DEPT_ID");t1.setField("DEPT_ID");var __t1=t.addColumn("EMPLOYEE_NAME");t1.setField("EMPLOYEE_NAME");var __t1=t.addColumn("SEX");t1.setField("SEX");var __t1=t.addColumn("BIRTHDAY");_t1.setField("BIRTHDAY");getViewModel().end(); </script>
代码 2.8:</d:View>输出的html内容
- 根据5的内容,BRich Engine会根据页面javascript来执行所有客户端代码。先根据客户端ViewModel的定义来新建所有的ViewModel客户端对象,然后根据不同的ViewModel客户端对象来初始化自己ViewModel的内容,先初始化客户端Datasets,然后进入ViewModel客户端的onDatasetsPrepared事件,然后初始化Controls(如跟Dataset绑定了关系,会根据Dataset来初始化这些绑定关系的Controls),然后进入ViewModel客户端的onLoad事件(另:ViewModel客户端的onUnLoad事件是在页面离开的时候触发)。
初始化Datasets和Controls都是一个很复杂的过程,都是根据Dorado5客户端封装好的javascript function来做的。初始化Datasets会先根据Dataset在客户端输出的javascript属性进行设置,然后给Dataset添加DoradoEvent(Dorado5事件,这些事件一般触发的是开发者对Dataset定义的对应事件,如没有定义有时候会执行默认的事件内容或者任意逻辑也不执行),再根据页面输出来的该Dataset XML数据对Dataset进行客户端新增数据记录。初始化Controls会先根据Control在客户端输出的javascript属性进行设置,然后根据Control绑定的Dataset来进行一些跟数据相关的属性设置,接下来是Control根据绑定的Dataset和自己的属性通过DHtml来生成页面该Control的Html子元素,然后给Control或者子对象添加DoradoEvent,给该Control下的DHTML 添加SystemEvent(系统事件的监听器)。Controls的初始化过程不是绝对的,因不同的控件类型而不同,初始化的顺序或者内容也可能不同。