下面我们通过实做AJAX对Dorado7中的AJAX操作做一定的了解。
页面功能描述:
首先我们设计一个Spring的JavaBean:
package com.bstek.dorado.sample.basic; import java.util.Properties; import org.springframework.stereotype.Component; import com.bstek.dorado.annotation.Expose; import com.bstek.dorado.core.DoradoAbout; @Component public class Ajax { @Expose public String toUpperCase(String str) { return "input:\n" + str + "\n\n" + "output:\n" + str.toUpperCase(); } @Expose public int multiply(int num1, int num2) { return num1 * num2; } @Expose public Properties getSystemInfo() { Properties info = new Properties(); info.setProperty("product", DoradoAbout.getProductTitle()); info.setProperty("vendor", DoradoAbout.getVendor()); info.setProperty("version", DoradoAbout.getVersion()); return info; } }
页面上放置三个按钮:button1, button2, button3
- 单击button1的时候,调用spring中的一个bean的方法toUpperCase,并将我们传入的字符串转换为大写,并返回到前台浏览器中;
- 单击button2的时候,调用spring中的一个bean的方法multiply,并将我们传入Map对象(含多个key)中的两个数字相乘,并将计算结果返回到前台浏览器中;
- 单击button1的时候,调用spring中的一个bean的方法getSystemInfo,并将Java中的一个Map对象返回到前台浏览器中;
如果完成了以上的三个功能,我们就很容易解决这些AJAX技术问题:
- 如何调用Spring中bean中指定的业务方法;
- 如何传入一个单值给后台,并将调用结果为单值的值如何返回到前台;
- 如何传入一个map到后台,并将运算结果返回到前台;
- 如何调用后台的业务方法,并将计算结果为map的值返回到前台;
掌握了以上基本技术之后,再将它们综合应用一下,如JS中指定map参数,ajax调用结束之后返回map对象,并在前端使用。这样我们就可以解决大部分的ajax调用问题了。
toUpperCase
下面我们还是在HelloWorld中实做这个范例,由于HelloWorld中已经定义过Ajax这个Bean了,我们不再重复定义,我们在com.bstek.dorado.sample.training目录中新建一个名称为Ajax的View,并在其中添加一个AjaxAction控件和Button控件,其中AjaxAction是Action的一种,我们在控件的基础知识中简单介绍过它代表了页面上的一种动作,是不可见的对象。但是它可以被其他可见控件使用,例如单击按钮时触发Action。
我们设置AjaxAction控件的相关属性:
属性 | 值 |
---|---|
id | toUpperCaseAction |
caption | To UpperCase |
parameter | Hello World! |
service | ajax#toUpperCase |
其中我们特别关注其service属性,"ajax#toUpperCase"是一个服务名称,根据Dorado中的服务定位表达式,它最终代表的含义是调用Ajax这个类的toUpperCase方法,至于服务表达式的概念我们后面再讲,这儿我们只要记住这个字符串最终会调用到Ajax这个类的toUpperCase方法就可以。而parameter的值就代表了调用toUpperCase方法传入的参数值。
再设置Button控件的相关属性:
属性 | 值 |
---|---|
action | toUpperCaseAction |
定义action属性的效果是,单击按钮的时候自动触发toUpperCaseAction。我们可以注意到Button上的显示内容我们都没有定义,该处根据Action的绑定规则它会自动显示action对应的caption,而toUpperCaseAction中我们已经定义了caption了。
另外,当Ajax这个类的toUpperCase方法执行结束之后,我们希望在浏览器中看到最终的返回值,那么我们定义toUpperCaseAction的onSuccess事件:
在当前目录下新建Ajax.js文件,输入如下代码:
// @Bind #toUpperCaseAction.onSuccess !function(self){ dorado.MessageBox.alert(self.get("returnValue")); }
在action的onSuccess事件中,self代表了action本身,returnValue表示Ajax调用结束后Java层返回的结果。该处关于JS代码的写法后面我们会有专门的章节进行说明,此处我们记住self.get("returnValue")的含义就是获得ajax调用返回的结果就可以。
这样我们就完成了第一个按钮的开发,在浏览器中打开这个页面(http://localhost:8080/sample-center/com.bstek.dorado.sample.training.Ajax.d)查看效果:
multiply
下面我们接着做multiply的ajax调用,同样我们再添加一个AjaxAction和一个Button。
我们设置AjaxAction控件的相关属性:
属性 | 值 |
---|---|
id | multiplyAction |
executingMessage | Computing... |
service | ajax#multiply |
通过toUpperCase实例的制作,我们知道了"ajax#multiply",它最终代表的含义是调用Ajax这个类的multiply方法。executingMessage是用于在Ajax调用时给客户一个提示信息,在Ajax调用结束之后会自动消失,这样对于某些耗时的ajax调用来说这种显示效果更为人性化。
再设置Button控件的相关属性:
属性 | 值 |
---|---|
id | multiplyButton |
action | multiplyAction |
caption | Ajax Multiply |
定义action属性的效果是,单击按钮的时候自动触发toUpperCaseAction。另外与toUpperCase范例不同,这次我们直接在Button上定义caption,其实这几种定义caption的方式都可行,根据实际场景灵活运用就是了。例如我们希望动态改变按钮绑定的action时,我们就可以考虑将caption定义在action中。
另外,当Ajax这个类的multiply方法被调用时需要两个参数,我们希望给用户一个自定义输入参数的机会,而不是toUpperCase用例中直接定义在parameter属性中,如下图:
则我们在Ajax.js中给button1的onClick代码中添加如下的JS:
// @Bind #multiplyButton.onClick !function(){ var action = view.get("#action1"); dorado.MessageBox.prompt("Please input two numbers here",{ defaultText: "3,5", callback: function(text){ var nums = text.split(","); var parameter = { num1: nums[0], num2: nums[1] }; action.set("parameter", parameter).execute(function(result){ dorado.MessageBox.alert(nums[0] + " * "+ nums[1] + " = " + result); }); } }); }
其中我们通过Dorado提供的MessageBox做用户输入界面,MessageBox的具体用法参考:http://www.bsdn.org/projects/dorado7/deploy/jsdoc/class.html?symbol=dorado.MessageBox.
我们将用户输入的值利用js的split拆分为两个数字,num1和num2封装到parameter中(可以想象成一个Map),并将这个parameter设置给action去调用服务器端的multiply方法。
我们回过头在看看multiply方法:
@Expose public int multiply(int num1, int num2) { return num1 * num2; }
当map对象传到Ajax类的时候,发现没有匹配的方法,这个时候Dorado的自动方法适配机制会自动的将map拆为num1和num2,从而调用到multiply方法。有关自动方法适配我们后面还会再讲。multiply做的工作就是将num1和num2相乘,并将结果返回。我们在Button的onClick代码中利用了一个回调函数将计算结果显示出来(回调函数用法会在后面的JavaScript基础中进一步说明)。
这样我们就完成了第二个按钮的开发,在浏览器中打开这个页面(http://localhost:8080/sample-center/com.bstek.dorado.sample.training.Ajax.d)查看效果:
getSystemInfo
下面我们做getSystemInfo的ajax调用,同样我们再添加一个AjaxAction和一个Button。
我们设置AjaxAction控件的相关属性:
属性 | 值 |
---|---|
id | getSystemInfoAction |
caption | Retrieve Dorado7 System Information |
service | ajax#getSystemInfo |
通过toUpperCase实例的制作,我们知道了"ajax#getSystemInfo",它最终代表的含义是调用Ajax这个类的getSystemInfo方法。
再设置Button控件的相关属性:
属性 | 值 |
---|---|
action | getSystemInfoAction |
定义action属性的效果是,单击按钮的时候自动触发getSystemInfo。
另外,当Ajax这个类的getSystemInfo方法调用成功后返回的是一个Properties对象,这也是一个Map对象,我们希望在浏览器中看到最终的返回值,那么我们在Ajax.js中定义getSystemInfoAction的onSuccess事件:
// @Bind #getSystemInfoAction.onSuccess !function(self){ var info = self.get("returnValue"); dorado.MessageBox.alert("product : " + info.product + "\n" + "vendor : " + info.vendor + "\n" + "version : " + info.version); }
在action的onSuccess事件中,self代表了action本身,returnValue表示Ajax调用结束后Java层返回的结果。由于返回的是一个Map对象,在浏览器中接受的时候会自动转为JSON对象,这样我们就可以直接通过info.product,info.veneor,info.version范围map中的内容。
这样我们就完成了第三个按钮的开发,在浏览器中打开这个页面(http://localhost:8080/sample-center/com.bstek.dorado.sample.training.Ajax.d)查看效果:
Attachments:
AjaxAction2Browser.png (image/png)
AjaxAction1Control.png (image/png)
AjaxAction1Browser.png (image/png)
AjaxAction1Event.png (image/png)
AjaxAction2Control.png (image/png)
AjaxAction3Browser.png (image/png)
AjaxAction3Control.png (image/png)