以前只了解一点C#、JS和ArcEngine、ArcIMS,并不了解AJAX、ArcServer,下面是这段时间总结的一些经验,语言描述可能不是很专业,但绝对实用。
Callback回调机制(我的理解):前台的操作和后台处理可以异步进行,前台需要后台做某些事情时,通过JS将参数以字符串的形式传入后台,后台进行解析,然后将结果以字符串的形式传回前台,前台JS程序根据传回的结果刷新局部页面。ICallbackEventHandler接口将两者联系起来,你只需按照ICallbackEventHandler接口里定义的方法和参数完成自己的事情即可。
1.在Default.aspx页面的JS代码中实现前台函数与参数的传入
<script language="javascript" type="text/javascript">
function MyFunctionClient(a)
{
var context = 'Map1';
var message = 'EventArg=MyFunction&a=' + a;
<%=ADFCallbackFunctionString%>
}
</script>
2.在Default.aspx.cs页面的Page_Load函数中定义前台的回调函数及相关参数
m_ADFCallbackFunctionString = Page.ClientScript.GetCallbackEventReference(this, "message",
"ZprocessCallbackResult", "context", "postBackError", true);
//这里要特别注意ESRI的默认前台回调处理为processCallbackResult,这里最好定义自己的处理函数,在自己定义
//的JS处理函数中将非ADF控件和ADF控件的处理函数分别处理,如果你在JS中重写了processCallbackResult函
//数,那么就将ESRI默认的回调处理函数覆盖了。
3.让 partial class Default类继承ICallbackEventHandler接口,并实现ICallbackEventHandler接口的方法,在RaiseCallbackEvent方法中解析前台传入的函数及参数:
public void RaiseCallbackEvent(string eventArgs)
{
if (nameValueCollection["EventArg"] == "getTreeNodeFilesList")
{
CallbackResult cResult = csFunction(nameValueCollection["a"]);//对前台的请求进行处理
//ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult cResult =
// new CallbackResult("javascript", "panelFilesResult", "showFilesListWin", myArrayList);关于CallbackResult参考//ESRI帮助
CallbackResultCollection cCallbackResults = new CallbackResultCollection();
cCallbackResults.Add(cResult);
m_CallbackResults = cCallbackResults.ToString();//将处理好的结果以字符串的形式返还到前台
}
}
4.在前台解析后台返回的字符串
function ZprocessCallbackResult(response, context) {
if(!response) { return; }
var results=[];
if(response.startsWith('///:::')) { //9.2 callback result format - OBSOLETE
var pairs = response.split("^^^");
for (var k=0;k<pairs.length;k++) {
var item = pairs[k];
if (item===null || item.length===0) { continue; }
var actions = item.split(":::");
if(actions.length<3) { continue; }
var type = actions[0].toLowerCase();
var cntlID = actions[1];
var actn = actions[2].toLowerCase();
var pars = [];
for(var j=3;j<actions.length;j++) {
Array.add(pars,actions[j]);
}
Array.add(results,{"id":cntlID,"type":type,"action":actn,"params":pars});
}
}
else { //JSON formatted callbackresults
try { results = eval(response); }
catch(ex) {
Sys.Debug.trace('Failed to process page response: "' + response + '"');
return;
}
}
ESRI.ADF.System.resetSessionLapse();
var validResponse = false;
for (var idx=0;idx<results.length;idx++)
{
var result = results[idx];
var controlID = result.id;
var controlType = result.type;
var obj = null;
if(controlID) { obj = $find(controlID); }
var action = result.action.toLowerCase();
var params = result.params;
if(action==='javascript') {
var method = function() {
try { eval(params[0]); }
catch(ex) { Sys.Debug.trace('CallbackResult[javascript]: Could not evaluate JavaScript: ' + params[0] +'\\n' + ex.name+' (' + ex.number + '):\\n' + ex.message); }
};
if(obj || context) {
//If there is an object or context, perform the javascript in the context of that
Function.createDelegate(obj?obj:context,method)();
}
else { method(); }
validResponse = true;
continue;
}
else if (action==="content") {
var o = $get(controlID);
if (o) { o.outerHTML=params[0]; }
else { Sys.Debug.trace('CallbackResult[content]: Element "' + controlID + '" not found'); }
validResponse = true;
continue;
}
else if (action==="innercontent") {
var o2 = $get(controlID);
if (o2) { o2.innerHTML=params[0]; validResponse = true; }
else { Sys.Debug.trace('CallbackResult[innercontent]: Element "' + controlID + '" not found'); }
continue;
}
else if (action==="image")
{
var o3 = $get(controlID);
if (o3) { o3.src = params[0]; }
else { Sys.Debug.trace('CallbackResult[image]: Image element "' + controlID + '" not found'); }
validResponse = true;
continue;
}
else if (action==="set")
{
if(obj) {
var properties = params[0];
if(String.isInstanceOfType(params[0])) {
properties = eval('('+params[0]+')');
}
for(var name in properties) {
var val = properties[name];
var setter = obj["set_" + name];
if (setter && typeof(setter) === 'function') { setter.apply(obj, [val]); }
else { obj.name = val; }
}
}
else { Sys.Debug.trace('CallbackResult[set]: Component "' + controlID + '" not found'); }
validResponse = true;
continue;
}
else if (action==='invoke') {
var method = null;
var methodname = params[0];
if(obj) { //Find method on object
method = obj[methodname];
}
else if(!controlID) { //if no object, look for global method
try { method = eval('('+methodname+')'); }
catch(ex) { }
}
else {
Sys.Debug.trace('CallbackResult[invoke]: Component "' + controlID + '" not found');
continue;
}
if(method && typeof(method) == 'function') {
var args = params[1];
if(args) {
if(Array.isInstanceOfType(args)) { method.apply(obj,args); }
else { method.apply(obj,[args]); }
}
else { method.apply(obj); }
}
else { Sys.Debug.trace('CallbackResult[invoke]: Invalid method "' + (controlID?controlID+'.':'')+methodname + '"'); }
validResponse = true;
continue;
}
else if (action=='include') {
var id = params[0];
var elm = (id?$get(id):null);
if(elm) { elm.parentNode.removeChild(elm); }
elm=null;
var src = params[1];
var tagname = params[2];
var type = params[3];
var language = params[4];
elm = document.createElement(tagname);
if(id) { elm.id = id; }
if(tagname==='link') { elm.href = src; }
else { elm.src = src; }
if(type) {
elm.type = type;
if(type==='text/css') { elm.rel = 'stylesheet'; }
}
if(language) { elm.language = language; }
document.getElementsByTagName('head').item(0).appendChild(elm);
validResponse = true;
continue;
}
else if(obj && obj.processCallbackResult) {
processCallbackResult(response, context);//ESRI默认的前台回调处理函数
return;
continue;
}
else if (obj && !obj.processCallbackResult) {
processCallbackResult_custom(result.action,params);//自己定义的前台回调处理函数
return;
}
if(!validResponse) {
Sys.Debug.trace('CallbackResult action "' + action+ '" couldn\'t be processed.');
}
}
if (validResponse)
{
lastResponseReceivedTime=new Date();
}
}
//自定义回调处理函数
function processCallbackResult_custom(action,params) {
if(action==="showFilesListWin") {
gfileresult = null;
if(params.length==0)return;
var fileResults = params[0];
showFilesListGrid(fileResults);
}
else if(action=='error') {
if(this.waitIcon) { map.removeGraphic(this.waitIcon); }
alert("Error: " + params[0]);
Sys.Debug.trace ('Error: '+params[0])
}
}
上述代码中不清楚的地方可以参考ARC安装下的Common_Callback程序示例。