扩展Dorado5原有Control
我们想对DataTable增加多一个marmotProfileKey属性,我需要做以下步骤:
- 新增MarmotDataTable.java,该类继承com.bstek.dorado.view.control.table.DataTable:
代码 5.2:MarmotDataTable.java
package org.marmot.framework.dorado;
import com.bstek.dorado.view.ViewModel;
public class MarmotDataTable extends
com.bstek.dorado.view.control.table.DataTable {
private String marmotProfileKey;
public MarmotDataTable(ViewModel viewModel, String id) {
super(viewModel, id);
}
public String getMarmotProfileKey() {
return marmotProfileKey;
}
public void setMarmotProfileKey(String marmotProfileKey) {
this.marmotProfileKey = marmotProfileKey;
}
} - 对DataTable对应类的定义,在home下新建controls.xml:
代码 5.3:controls.xml
<?xml version="1.0" encoding="UTF-8"?>
<controls>
<control type="DataTable" clazz="org.marmot.framework.dorado.MarmotDataTable"/>
</controls>
经过上面的处理,就可以给DataTable增加了marmotProfileKey属性,在开发器或者Java代码中就可以对marmotProfileKey赋值。
如我们想把marmotProfileKey通过Js赋值给客户端的DataTable,那我们就要通过DataTable的Outputter来实现: - 新增MarmotDataTableOutputter.java,该类继承com.bstek.dorado.view.smartweb.v2.output. DataTableOutputter:
代码 5.4:MarmotDataTableOutputter.java
public class MarmotDataTableOutputter extends
com.bstek.dorado.view.smartweb.v2.output. DataTableOutputter {
public void doOutputRegisterSection(Writer writer, Object object, ServletRequest request)
throws Exception
{
super.doOutputRegisterSection(writer, object, request);
DataTable table = (DataTable)object;
writer.write(JavaScriptHelper.scirptSetProperty(table, "marmotProfileKey"));
}
} - 对DataTable Outputter对应类的定义,在home下新建outputters.xml:
代码 5.5:outputters.xml
<?xml version="1.0" encoding="UTF-8"?>
<elements>
<element clazz="org.marmot.framework.dorado.MarmotDataTable">
<outputter type="smartweb2" clazz="com.bstek.dorado.view.smartweb.v2.output.MarmotDataTableOutputter"/>
</element>
</elements>
如想对DataTable的Html输出作出改变,那就在MarmotDataTableOutputter里对doOutputStartSection和doOutputEndSection做修改。
扩展Dorado5原有Control为新Control
根5.3.1的设置一样,只是在定义类型的时候,定义新的Control类型而不是覆盖旧的Control类型定义。 - 首先要修改controls.xml:
代码 5.6:controls.xml
<?xml version="1.0" encoding="UTF-8"?>
<controls>
<control type="MarmotDataTable" clazz="org.marmot.framework.dorado.MarmotDataTable"/>
</controls> - 打开sutdio/configs/user-view-rules.xml文件(如果没有请在该目录下创建一个,如已存在,请把每个子项放在对应的位置下),添加如下代码:
代码 5.7:user-view-rules.xml
<?xml version="1.0" encoding="UTF-8"?>
<rules>
<rule name="Controls" expanded="true" showDetail="false">
<children>
<child name="Control-MarmotDataTable" insertable="true" defaultNamePrefix="marmotDataTable "/>
</children>
<palette>
<item label="CustomControls" icon="folder-opened.png">
<item name="Control-MarmotDataTable"/>
</item>
</palette>
</rule>
<rule name="Control-MarmotDataTable" text="MarmotDataTable" tagName="Control" object=" org.marmot.framework.dorado.MarmotDataTable" nameAttribute="id" editable="true" icon="view/datatable.png">
<properties>
<property name="type" visible="false" defaultValue=" MarmotDataTable"/>
<property name="id" required="true"/>
</properties>
<children>
<child name="Column" insertable="true" defaultNamePrefix="group"/>
</children>
<functions>
<function text="Auto create columns" icon="view/create-element.png" clazz="com.bstek.designer.impl.view.DataTableCreateColumnFunction"/>
</functions>
</rule>
</rules>
图 5.1:
重启IDE,打开任意一个ViewModel,我们会发现在左边的工具条上多了一个MarmotDataTable的图标。 - 最后一步,在我们的JSP里面要使用我们的MarmotDataTable,标签需要采用如下方式进行定义:
代码 5.8:jsp
<d:Control id="marmotDataTable1" type="MarmotDataTable"/>
新建页面不带控制的静态Control
对于一些静态的Html输出到页面,最经常使用的就是通过标签来实现,在继承TagSupport下在doStartTag和doEndTag对Html输出就可以了。
在Dorado5里我们把这些步骤放在了Outputter里,这样为了方便Dorado5进行统一管理,也不需要再定义标签等等。
比如我做一个静态Table输出到页面,数据来至于Dataset。页面如下:
图 5.2: - 先定义初始化控件的类,因为新的控件是一个页面可见的控件,那该类就继承于com.bstek.dorado.view.control.PlaceableDataControl:
代码 5.9:TestCustomTable.java
package test;
import com.bstek.dorado.view.ViewModel;
import com.bstek.dorado.view.control.PlaceableDataControl;
public class TestCustomTable extends PlaceableDataControl{
public TestCustomTable(ViewModel viewModel, String id) {
super(viewModel, id);
}
} - 把上面java代码打包成jar包放在sutdio/lib文件夹下:
图 5.3:
- 打开sutdio/configs/user-view-rules.xml文件(如果没有请在该目录下创建一个,如已存在,请把每个子项放在对应的位置下),添加如下代码:
代码 5.9:user-view-rules.xml
<?xml version="1.0" encoding="UTF-8"?>
<rules>
<rule name="Controls">
<children>
<child name="Control-TestCustomTable" insertable="true" defaultNamePrefix="testCustomTable"/>
</children>
<palette>
<item label="CustomControls" icon="folder-opened.png">
<item name="Control-TestCustomTable"/>
</item>
</palette>
</rule>
<rule name="Control-TestCustomTable" text="TestCustomTable" tagName="Control" object="test.TestCustomTable" nameAttribute="id" editable="true" icon="view/table.png">
<properties>
<property name="type" visible="false" defaultValue="TestCustomTable"/>
<property name="id" required="true"/>
</properties>
</rule>
</rules>
- 重启IDE,打开任意一个ViewModel,我们会发现在左边的工具条上多了一个TestCustomTable的图标。
图 5.4:
- 打开Dorado工程的home/ controls.xml文件(如果您的目录下没有,请创建一个新的),添加下列代码:
代码 5.10:controls.xml
<?xml version="1.0" encoding="UTF-8"?>
<controls>
<control type="TestCustomTable" clazz="test.TestCustomTable"/>
</controls>
- 打开Dorado工程下home/ outputters.xml文件,添加下列代码:
代码 5.11:outputters.xml
<?xml version="1.0" encoding="UTF-8"?>
<elements>
<element clazz="test.TestCustomTable">
<outputter type="smartweb2" clazz="test.TestCustomTableOutputter"/>
</element>
</elements>
- TestCustomTableOutputter类的代码为:
代码 5.12:TestCustomTableOutputter.java
package test;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.ServletRequest;
import com.bstek.dorado.data.Dataset;
import com.bstek.dorado.data.Record;
import com.bstek.dorado.data.RecordIterator;
import com.bstek.dorado.view.smartweb.v2.output.AbstractPlaceableControlOutputter;
import com.bstek.dorado.view.smartweb.v2.output.HtmlHelper;
import com.bstek.dorado.view.smartweb.v2.output.JavaScriptHelper;
public class TestCustomTableOutputter extends AbstractPlaceableControlOutputter{
public TestCustomTableOutputter()
{
}
public void doOutputStartSection(Writer writer, Object object, ServletRequest request)
throws Exception
{
TestCustomTable testCustomTable = (TestCustomTable)object;
String namespace = testCustomTable.getViewModel().getNamespace();
writer.write("<table id=\"");
writer.write(JavaScriptHelper.getReadId(namespace, testCustomTable.getId()));
writer.write("\" ");
writer.write("<table ");
writer.write(HtmlHelper.tagProperty("border","1"));
writer.write(HtmlHelper.tagProperty("height",testCustomTable.getHeight()));//在设计器里定义
writer.write(HtmlHelper.tagProperty("width",testCustomTable.getWidth()));//在设计器里定义
writer.write("><tr>");
String dsid = testCustomTable.getDataset();
Dataset ds = testCustomTable.getViewModel().getDataset(dsid);
int fieldCount = ds.getFieldCount();
for (int i = 0; i < fieldCount; i++) {
writer.write("<td>");
writer.write(ds.getField.getLabel());
writer.write("</td>");
}
writer.write("</tr>");
}
public void doOutputEndSection(Writer writer, Object object,ServletRequest servletrequest) throws Exception {
//这里还可以做成有Column,根据Column属性来输出html
TestCustomTable testCustomTable = (TestCustomTable)object;
String dsid = testCustomTable.getDataset();
Dataset ds = testCustomTable.getViewModel().getDataset(dsid);
Record current = ds.getCurrent();//for test
if(current == null){
ds.load();
}
int fieldCount = ds.getFieldCount();
RecordIterator ri = ds.recordIterator();
ri.setVisibility(Dataset.FILTER_ALL);
while(ri.hasNext()) {
Record record = ri.nextRecord();
writer.write("<tr>");
for (int i = 0; i < fieldCount; i++) {
writer.write("<td>");
writer.write(record.getString(ds.getField.getName()));
writer.write("</td>");
}
writer.write("</tr>");
}
writer.write("</table>");
}
public void doOutputRegisterSection(Writer writer, Object object, ServletRequest request)throws IOException
{//js
}
} - 在我们的JSP里面要使用我们的TestCustomTable,标签需要采用如下方式进行定义:
代码 5.13:jsp
<d:Control id="testCustomTable1" type="TestCustomTable"/>
- 例子中的view.xm代码为:
代码 5.13:view.xml
<?xml version="1.0" encoding="UTF-8"?>
<view>
<Datasets>
<Dataset id="dataset1" type="Custom" listener="test.test_dataset1Listener">
<MasterLink />
<Fields>
<Field name="field1" label="字段1">
<Properties />
</Field>
<Field name="field2" label="字段2">
<Properties />
</Field>
<Field name="field3" label="字段3">
<Properties />
</Field>
</Fields>
<Parameters />
<Properties />
</Dataset>
</Datasets>
<Controls>
<Control id="testCustomTable1" type="TestCustomTable" dataset="dataset1" />
</Controls>
<Properties />
</view>
新建页面带事件控制的Control
我们根据5.3.3实现的静态Table来实现点击Table的时候弹出Table对应Dataset的信息出来。我只需要在TestCustomTableOutputter类里增加doOutputRegisterSection方法来输出js就可以了:代码 5.14:TestCustomTableOutputter.java。。。
public void doOutputRegisterSection(Writer writer, Object object, ServletRequest request)throws IOException
{
TestCustomTable testCustomTable = (TestCustomTable)object;
String dsid = testCustomTable.getDataset();
writer.write("EventManager.addSystemEvent("testCustomTable.getId()",\"onmousedown\",function(event){alert("dsid");});");
}
。。。
出来的页面效果是:
新建页面动态Control
这个需要Dhtml技术和页面事件来实现,一般是对Dorado5新增一些控件才能用到,对于一般客户做扩展和封装会存在很大的难度,这里就不写出来。
新建通过Dataset驱动的动态Control
请结合上面的内容和《dorado5组件扩展----自定义组件对象client端编程》。
我们把5.3.4的实现放在js中,再加上通过Dataset驱动简单实现。 - 修改TestCustomTableOutputter类里的doOutputRegisterSection方法来改变输出js内容:
代码 5.15:TestCustomTableOutputter.java
。。。
public void doOutputRegisterSection(Writer writer, Object object, ServletRequest request)throws Exception
{
TestCustomTable testCustomTable = (TestCustomTable)object;
//String dsid = testCustomTable.getDataset();
//writer.write("EventManager.addSystemEvent("testCustomTable.getId()",\"onmousedown\",function(event){alert("dsid");});");
outputCreateSection(writer, testCustomTable, "TestCustomTable");
ViewModel viewModel = testCustomTable.getViewModel();
writer.write(JavaScriptHelper.scirptSetDataset(viewModel, testCustomTable, "dataset"));
writer.write(JavaScriptHelper.scirptSetProperty(testCustomTable, "tag"));
outputEvent(writer, testCustomTable, "__t");
}
。。。
这里为了输出根据id创建一个TestCustomTable控件(js),还有Js TestCustomTable控件所需要的属性。 - 在home/smartweb/v2/lib文件夹下新建TestCustomTable.js,内容是注册新的控件类型(TestCustomTable):
代码 5.16:TestCustomTable.js
/**
* 定义TestCustomTable控件的属性和控制等
* @param {Object} id
* @param {Object} n
*/
function TestCustomTableF(id, n) {
var testCustomTable = document.getElementById(id);
testCustomTable.setDataset=__DataControl_setDataset;
testCustomTable.getDataset=__DataControl_getDataset;
testCustomTable.establishBinding = __DataControl_establishBinding;
testCustomTable.disableBinding = __DataControl_disableBinding;
testCustomTable.enableBinding = __DataControl_enableBinding;
testCustomTable.activate = __DataControl_activate;
EventManager.addSystemEvent(testCustomTable,"onmousedown",function(event){alert(testCustomTable.getDataset());});
testCustomTable.processDatasetMessage=testCustomTable_processDatasetMessage;
return testCustomTable;
}
/**
* TestCustomTable控件运行时消息处理机制
* @param {Object} message
* @param {Object} dataset
* @param {Object} args
*/
function testCustomTable_processDatasetMessage(message, dataset, args) {
switch (message) {
case __Dataset_MSG_REFRESH: {
alert(dataset.getId()+" REFRESH!");
break;
}
case __Dataset_MSG_REFRESH_RECORD: {
alert(dataset.getId()+" REFRESH_RECORD!");
alert(args[0]);
break;
}
case __Dataset_MSG_DATA_CHANGED: {
alert(dataset.getId()+" DATA_CHANGED!");
alert(args[0]);
alert(args[1]);
alert(args[2]);
break;
}
case __Dataset_MSG_CURRENT_CHANGED: {
alert(dataset.getId()+" CURRENT_CHANGED!");
break;
}
case __Dataset_MSG_GAINING_CHANGE: {
alert(dataset.getId()+" GAINING_CHANGE!");
break;
}
case __Dataset_MSG_RECORD_DELETED: {
alert(dataset.getId()+" RECORD_DELETED!");
alert(args[0]);
break;
}
case __Dataset_MSG_STATE_CHANGED: {
alert(dataset.getId()+" STATE_CHANGED!");
break;
}
case __Dataset_MSG_RECORD_STATE_CHANGED: {
alert(dataset.getId()+" RECORD_STATE_CHANGED!");
alert(args[0]);
break;
}
}
}
DoradoFactory.registerComponentType("TestCustomTable",TestCustomTableF);
上面代码通过DoradoFactory.registerComponentType("TestCustomTable",TestCustomTableF);来注册了新的控件(TestCustomTable),TestCustomTableF是对新控件的属性定义和初始化设置等。testCustomTable_processDatasetMessage方法是由于Dataset的消息机制执行了该方法,所以可以在这个方法里实现对本控件的一些控件处理等等。原本在5.3.4中处理的方法现在放在了初始化这个控件的时候给onmousedown事件它,跟原来的实现是一样的。 - 在home文件夹下新建javascript-lib.xml,用来输出TestCustomTable.js:
代码 5.17:javascript-lib.xml
<?xml version="1.0" encoding="UTF-8"?>
<libraries>
<library name="TestCustomTable" path="TestCustomTable.js" />
</libraries> - 运行效果:
初始化页面的时候会弹出"dataset1 REFRESH!"对话框,是因为dataset1刚进来页面的时候做了一次刷新动作,触发了processDatasetMessage,从而进入了testCustomTable_processDatasetMessage方法处理弹出对话框。
尝试在Dorado Client Debugger里对dataset做一些操作,看能不能触发TestCustomTable控件的处理。
从上面由于对dataset1改变field1的值(原来值为field11,现在变成""),所以触发了processDatasetMessage,弹出的对话框也很符合testCustomTable_processDatasetMessage的代码逻辑。
通过上面的一些例子,我们就可以自己去实现各种各样的控件,从简单到复杂,只要你能想到就可能做到,这个要看写代码的程度。上面还有很多功能没有说到,但最基本和最基础的内容都罗列了出来,通过这些简单的例子,就可以实现复杂的控件出来了。一般复杂的控件需要结合Dhtml、事件触发和消息机制等等技术来实现。
Attachments:
worddavf865142d05bb7de56aeb8531cf0dbd0d.png (image/png)
worddavae47259a82816056f88a4ae7edabd748.png (image/png)
worddaveec304624175714033a5ad834a5203d2.png (image/png)
worddav5e3c54ad82e1cfc35ae5b1b136fa0e6f.png (image/png)
worddav9318cf52e90df39d761e18f719e851c0.png (image/png)
worddav94dfdda92faa3684cda68a37fc9f2289.png (image/png)
worddav0b3aafcd7d52238e65cf57dce5f2605e.png (image/png)
worddavb099969a426c81ff03e0a1a0ac300c85.png (image/png)
worddave6d50b3bd4583bca3c8e1c9e26af0229.png (image/png)
worddave9837f8db483040993a458b0893da299.png (image/png)
worddave6e7a2e6134fac6ba9a6942a288384ea.png (image/png)