Dorado 5 : 1.3.3.RequestCommand(URL请求命令) (RF2)

简述

一个功能完整的页面,在实现业务功能的操作过程中,通常都可能存在多个URL请求,例如:

  • 页面跳转;
  • 打开新的window窗口;
  • 打开window子窗口;

通常情况下我们都会将这些请求以window.open()或form.action等的形式加以配置。并根据需要在url后面添加自定义的参数或form中添加隐含变量等等,以便在发出URL请求的同时传递相关的信息到服务器端,服务器根据请求的参数做进一步的处理。
在dorado中,这些请求一般都用RequestCommand对象封装,而通过RequestCommand对象的execute()方法实现URL请求的。

使用

RequestCommand的使用非常容易,一般都是通过设定它的path指定要请求的URL,而通过RequestCommand的parameters()传递参数信息
查看如下的xml配置代码:

<Control id="commandEdit" type="RequestCommand" path="contract-maintain.jsp">
<Frame />
<Parameters>
<Parameter name="id" value="ASN01001" />
</Parameters>
</Control>

该命令执行时会自动的向contract-maintain.jsp页面发出请求,并将id作为参数发送过去,执行效果等同于:

window.open("contract-maintain.jsp?id=ASN01001");

参数设定

url请求的参数可以通过两种方式实现:

  • 通过parameters()指定,可以参考QueryCommand的开发技巧1
  • 通过RequestCommand的dataset属性以及parameterFields属性指定

Dorado JSP中数据都由dataset管理,RequestCommand也提供了基于dataset的使用支持,查看如下的配置代码:

<Control id="cmdEdit"
type="RequestCommand"
path="contract-maintain.jsp"
dataset="dsContract" parameterFields="contract_no">
<Frame />
<Parameters>
<Parameter name="op" value="edit" />
</Parameters>
</Control>

通过指定parameterFields设置RequestCommand执行时自动的从dataset属性对应的dsContract中的当前记录获取contract_no信息,并作为RequestCommand请求的参数发送到contract-maintain.jsp。
如下图:

图表 15 合同维护查询界面
在上图的编辑合同按钮的onClick事件中,用下列脚本执行RequestCommand:

cmdEdit.execute();

根据前面的描述,cmdEdit会自动的从dsContract的当前记录中取出contract_no作为参数传递到contract-maintain.jsp中,由于当前dsContract定位的记录中的contract_no为SC060403,则上面cmdEdit.execute()的执行效果就等同于如下的代码:

window.open("contract-maintain.jsp?contract_no=SC060403&op=edit");

RequestCommand的parameterFields属性设定可以设置为多个字段,多个字段间用逗号(",")隔开,如:

<Control id="cmdEdit"
type="RequestCommand"
path="contract-maintain.jsp"
dataset="dsContract" parameterFields="contract_no,contract_name">
<Frame />
<Parameters>
<Parameter name="op" value="edit" />
</Parameters>
</Control>

另外关于parameterFields的使用还有一个默认规则:如果该属性为空,而dataset属性不为空,则RequestCommand运行时会自动的将相应的dataset的当前记录的所有字段的值作为参数传递到path指定的页面中去。

frame设置

对于一个新请求的页面,RequestCommand还提供了一个Frame对象设置新页面的基本特性,如:

<Control id="cmdEdit"
type="RequestCommand"
path="contract-maintain.jsp"
dataset="dsContract"
parameterFields="contract_no">
<Frame height="400"
width="600" statusbar="false"
resizable="false" center="true" target="_blank" />
<Parameters>
<Parameter name="op" value="edit" />
</Parameters>
</Control>

以上代码通过Frame节点设置新请求页面的高度为400,宽度为600,不显示状态栏,不允许改变大小,默认位于屏幕的中间,等.
Frame的非target属性在一种特殊的情况下是没有意义的:当frame的target的值为_self的时候,由于新请求页面是在本窗口打开,因此无法实现Frame中的各个属性配置。需要开发人员特别注意。
Frame的详细属性说明参考RequestCommand的主要属性说明

target设定

在RequestCommand中介绍了其中frame对象的作用以及基本使用方式。其中frame包含一个target属性,该属性是RequestCommand用来决定新URL请求打开的客户端窗口使用方式。
可设定的属性有:

  • _exclusive_subwindow:排它性的子窗口
  • _subwindow:普通子窗口
  • _self:打开新的页面替换本页面内容
  • _blank:在一个新的页面打开
  • _parent:在当前页面的父页面框架中打开
  • _top:在当前页面的最顶层框架页面打开
  • _modal_dialog:模态窗口
  • _modeless_dialog:非模态窗口

开发人员可以根据业务需求灵活的选择不同的打开方式。默认设置为"_self",也就是新请求的URL资源直接在本窗口显示。
同样上面的范例,如果我们将Command的定义修改为

<Control id="cmdEdit"
type="RequestCommand"
path="contract-maintain.jsp"
dataset="dsContract" parameterFields="contract_no">

<Frame target="_modal_dialog" width="411"
height="280" center="true" resizable="true" statusbar="false" />
<Parameters>
<Parameter name="op" value="edit" />
</Parameters>
</Control>

那么这段xml的配置与如下的一段js代码的作用相同:

window.showModalDialog("contract-maintain.jsp?op=edit&contract_no=SC060408", null, "dialogWidth:411px;dialogheight:280px;center:1;status:0;resizable:yes;");

method属性设定

Method属性用于设定ReqeustCommand参数传递的方式,默认情况下都是使用form的get方式,也就是使用url后直接加参数的方式明文调用,建议使用post方式传递参数,使用这种方式传递不仅可以提高安全性,也有利于解决参数传递的中文问题。

<Control id="cmdEdit"
type="RequestCommand"
path="contract-maintain.jsp" method="post"
dataset="dsContract" parameterFields="contract_no">

<Frame target="_modal_dialog" width="411"
height="280" center="true" resizable="true" statusbar="false" />
<Parameters>
<Parameter name="op" value="edit" />
</Parameters>
</Control>

很多开发人员喜欢通过RequestCommand给新的URL传递一个中文参数,对于这种Request的请求,目前在WEB系统中一直都不好处理。Dorado中我们建议的办法是通过QueryCommand中关于中文问题的处理办法 1.3.1.QueryCommand(查询命令) (RF2)#关于传递中文参数查询的处理办法,请参考。以上方式只是我们的一种建议,当然最好的处理方式是不要直接传递中文信息。

常用技巧

动态添加参数 1.3.2.UpdateCommand(更新命令) (RF2)#_动态添加参数,

动态编程

在服务器段动态生成RequestCommand

protected void initControls() throws Exception {
super.initControls();//系统默认函数,注意保留
RequestCommand cmdEdit = (RequestCommand)createControl("RequestCommand ", " cmdEdit");

cmdEdit.setDataset("dsContract");
cmdEdit.setParameterFields("contract_no");
cmdEdit.setPath("contract-maintain.jsp");

cmdEdit.getFrame().setWidth("600");
cmdEdit.getFrame().setHeight("400");
cmdEdit.getFrame().setTarget("_modal_dialog");
cmdEdit.getFrame().setCenter(true);
cmdEdit.getFrame().setResizable(true);
cmdEdit.getFrame().setStatusbar(false);

cmdEdit.parameters().setString("op", "edit");
}

使用视图模型实现类提供的createControl方法创建RequestCommand对象,注意第一个参数用以指定组件的类型,第二个参数指定新建对象的id

在服务器段获得View(视图模型)中定义的RequestCommand,并动态它的属性

protected void initControls() throws Exception {
super.initControls();//系统默认函数,注意保留
RequestCommand cmdEdit = (RequestCommand)getControl("cmdEdit");

cmdEdit.setDataset("dsContract");
cmdEdit.setParameterFields("contract_no");
cmdEdit.setPath("contract-maintain.jsp");

cmdEdit.getFrame().setWidth("600");
cmdEdit.getFrame().setHeight("400");
cmdEdit.getFrame().setTarget("_modal_dialog");
cmdEdit.getFrame().setCenter(true);
cmdEdit.getFrame().setResizable(true);
cmdEdit.getFrame().setStatusbar(false);

cmdEdit.parameters().setString("op", "edit");
}

在上面的代码中可以看到通过实现类提供的getControl函数获得我们需要的组件对象,所需要的就是给它一个RequestCommand对象的id,注意开发时我们建议您直接在View的设计中添加一个空RequestCommand组件,这样我们就可以在initControls方法中通过getControl方法获得这个空的RequestCommand对象,并利用该对象提供的API进行各种设定和初始化的工作,如RequestCommand的setPath(),setDataset(),frame的设定,parameters()的设定等等。

主要属性说明

属性

说明

dataset

命令绑定的dataset对象,与parameterFields属性配合使用,打开path指定的页面时将绑定dataset中指定的字段传入

parameterFields

用于指定打开path指定的页面时将绑定dataset中指定的字段传入,与dataset属性配合使用.可以同时指定多个字段,多个字段间以逗号分隔

path

命令执行时将要打开的页面的url

RequestCommand的Frame子节点的主要属性有:

属性

说明

center

新窗口是否自动居中,默认为true

height

新窗口的高度

left

新窗口距离屏幕左侧的象素值

resizable

是否允许改变新窗口大小,yes为允许

statusbar

新窗口是否显示状态栏内的信息,yes为允许

target

新窗口的打开方式
提供有:
_exclusive_subwindow:排它性的子窗口
_subwindow:普通子窗口
_self:打开新的页面替换本页面内容
_blank:在一个新的页面打开
_parent:在当前页面的父页面框架中打开
_top:在当前页面的最顶层框架页面打开
_modal_dialog:模态窗口
_modeless_dialog:非模态窗口

top

新窗口距离屏幕上方的象素值

width

新窗口的宽度

主要事件说明

参考QueryCommand对象的事件说明
由于target的不同RequestCommand中onSuccess与onFailure在所有的Command中还是有些特别,需要特别注意,下面分别说明:

Target

是否触发onSuccess事件

是否拥有返回值

子窗口方式(_subwindow, _exclusive_subwindow)

Dialog模式(_modal_dialog,_modeless_dialog)

替换模式(_blank,_self,_top,_parent)

新窗口模式(_blank)

RequestCommand不支持onFailure事件。
以上要出发onSuccess事件的target方式中,onSuccess的触发机制还不一样:
Dialog模式:该模式支持对象返回处理机制,因此RequestCommand的execute()方法执行时,就这么控制:

var target = frame.getTarget();
if (target == "_ subwindow"

target==" _exclusive_subwindow") {
result = this.openSubWindow(path, frame);
}
else if (target == "_modal_dialog"

target == "_modeless_dialog") {
result = this.openDialog(path, frame, arg);
this.fireOnSuccess();
}
else {
this.open(path, frame);
result = true;
this.fireOnSuccess();
}
return result;