什么,你不懂Ajax,好吧,那么 在开始之前,我们先看下Ajax的定义,

Ajax 是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写。Ajax由几种已有技术以新的强大方式组合:基于XHTMLCSS标准的表示;使用Document Object Model进行动态显示和交互;使用XMLHttpRequest与服务器进行异步通信;使用JavaScript绑定一切。

另外,我们来看看Callback机制,微软在ASP.NET 2.0中提出客户端Callback机制,其目的在于实现页面异步调用和无刷新局部显示。从技术角度分析,Callback机制就是对AJAX部分功能进行了封装(图2),其框架中提供全新接口ICallbackEventHandler用来指示控件作为服务器的回调事件的目标,通过接口的方法可轻松实现页面局部刷新技术。

ArcGIS Server在其最新的ArcGIS Server 9.2中为解决含有ADF组件页面局部刷新问题,在Asp.Net 2.0 Callback机制的基础上扩充引入了Ajax架构。所以从这点来看,.Net Callback 回调机制对于我们每一个学习ArcGIS Server 的人来说还是依然至关重要的!

我们说Callback机制实际上就是一个接口ICallbackEventHandler,提供了两个方法,

GetCallbackResult和RaiseCallbackEvent,其语法结构分别如下:

string GetcallbackResult();

void RaiseCallbackEvent(string eventArgument);

前者返回以控件为目标的回调事件的结果,后者处理以控件为目标的回调事件,即执行回调事件。通过以上两个方法回调所实现的功能主要是:从客户端接收一个数据参数,在服务器端获取这个参数,并执行一个实现所需功能的事件,最后返回客户端所需结果数据。因此,如果要应用Callback机制,Page就必须继承接口ICallbackEventHandler。 通俗点说,RaiseCallbackEvent就是接收客户端的指令,然后对其进行处理,然后通过GetcallbackResult返回给客户端。

另外,在.net中有一个函数可以使用客户端的脚本调用服务器端指定的函数。也就是通过这个方法才实现了.net中页面的无回调刷新的。

public string GetCallbackEventReference (Control control,string argument,string clientCallback,string context)
参数:
control 处理客户端回调的服务器 Control。该控件必须实现 ICallbackEventHandler 接口并提供 RaiseCallbackEvent 方法。
argument 从客户端脚本传递一个参数到服务器端的RaiseCallbackEvent 方法。
clientCallback 一个客户端事件处理程序的名称,该处理程序接收服务器端事件返回的结果。
context 启动回调之前在客户端的客户端脚本信息。脚本的结果传回给客户端事件处理程序。
返回值 调用客户端回调的客户端函数的名称。
返回服务器端的响应函数是没有选择的。必须是服务器端的RaiseCallbackEvent,因此当一个页面中有多个地方需要回调的时候,就需要使用参数来区分。
客户端的响应函数使用javascripts来写,没有什么问题,在这里把返回的结果刷新出来。
服务器端的实现代码放在RaiseCallbackEvent中,也没有什么问题。
还有一个问题就是GetCallbackEventReference这个函数放在哪里,
一个位置是放在page_load中,
m_copyrightCallback = Page.ClientScript.GetCallbackEventReference(Page,"argument","processCallbackResult","context",true);
另一个就是直接放在客户端的事件当中。

<%=ClientScript.GetCallbackEventReference(this,"imagechange","ShowServerTime2",null) %>

说了这么多,可能还是不太懂,我们举个例子来说明吧。

本例子主要是先实现查询,查询结果显示在页面上的一个DIV中,然后将查询结果在地图上定位显示,在地图上显示这个过程是定位到所查询结果要素所在的那个区域, 并且实现时整个页面看起来不刷新(实际也是在刷新),只是地图在刷新。

当然这个刷新的动态过程图片描述不出来,自己运行去看吧。


首先要加入map,mapresourcemanager,toolbar,toc等控件并设置关联,另外需要在mapresourcemanager中除了自己的要用的地图外,还添加一个name为Selection的资源,类型为Graphicslayer,其他操作都比较简单,在这里就省略了。

1、加入html控件

拖入一个html控件下的Text和两个Button 以及一个DIV,ID分别为:txtCommunitybtnCommunitybtnCommunity2,list1(其中Text用来输入查询的文字,btnCommunity用来查询,btnCommunity2用来在地图上地位,list1用来显示查询的结果)。然后分别单击获得两个Button的click事件,代码如下:

<script language="javascript" type="text/javascript">

function btnCommunity_onclick() {

//获取输入的查询关键字
var v=document.getElementById("txtCommunity").value;
//生成请求字符串
var argument = "ControlID=Map1&ControlType=Map&Type=queryC1&EventArg=" + v;
var context = "Map";
//m_Callback 由服务端的Page_load事件中生成的,用于请求服务端的js代码
var script=<%= m_Callback %>
//用eval执行字符串
eval(script);

}

function btnCommunity2_onclick() {


//获取输入的查询关键字

var v=document.getElementById("txtCommunity").value;
//生成请求字符串
var argument = "ControlID=Map1&ControlType=Map&Type=queryC&EventArg=" + v;
var context = "Map";
//m_Callback 由服务端的Page_load事件中生成的,用于请求服务端的js代码
var script=<%= m_Callback %>
//用eval执行字符串
eval(script);

}

//这个函数是用来实现查询结果的显示在页面中

function gocenger(id)
{
//请求字符串
var argument = "ControlID=Map1&ControlType=Map&Type=center&EventArg=" + id;
var context = "Map";
var script=<%= m_Callback %>
eval(script);
}

</script>

注意argument中的参数 ,其中Type与.cs文件的具体如何执行操作的判别有关,EventArg是从客户端传到服务器端的值(这里就是v的值)。

2、在.cs中,首先要实现 ICallbackEventHandler接口,这是实现页面局部刷新的基础。

public partial class _Default : System.Web.UI.Page,ICallbackEventHandler
{


public string m_Callback = "";

protected void Page_Load(object sender,EventArgs e)
{

//生成客户端脚本段
m_Callback = Page.ClientScript.GetCallbackEventReference(Page,true);

//这句话就是同上文所讲述的GetCallbackEventReference的调用
}


//以下就是实现的关键代码,可能有些垃圾代码,水平有限,请见谅。

#region ICallbackEventHandler 成员

private string _callbackArg;
//负责把结果回传给客户端
string ICallbackEventHandler.GetCallbackResult()
{
return RaiseCallbackEvent(_callbackArg);

}

//负责从客户端javascript传来的参数
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
_callbackArg = eventArgument;

}


//对客户端的请求进行处理
public virtual string RaiseCallbackEvent(string _callbackArg)
{



string v = "";//v是用来最后传给客户端的结果



NameValueCollection keyvalColl = CallbackUtility.ParseStringIntoNameValueCollection(_callbackArg);

//本例子是用来实现对地图中“社区”这一图层的查询,改成自己的数据即可,

if (keyvalColl["Type"].ToString() == "queryC1")//这个if中的语句用来实现查询的,
{

System.Text.StringBuilder sb = new System.Text.StringBuilder();
string Input = keyvalColl["EventArg"];//Input 即获得了页面中在Text 中输入的值


string str = "";


string targetlayername = "社区";

//获取Data Layers的MapFunctionality
ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)Map1.GetFunctionality(1);
ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = mf.Resource;
//是否支持QueryFunctionality
bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
if (supported)
{
//创建QueryFunctionality
ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality),null);
string[] lids;
string[] lnames;
//查询图层的id和名称
qfunc.GetQueryableLayers(null,out lids,out lnames);

int layer_index = 0;
//获取目标图层的index
for (int i = 0; i < lnames.Length; i++)
{
if (lnames[i] == targetlayername)
{
layer_index = i;
break;
}

}
//空间过滤
ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter();
//是否返回地理元素
spatialfilter.ReturnADFGeometries = false;
//返回最大记录数
spatialfilter.MaxRecords = 1000;
spatialfilter.Geometry = Map1.GetFullExtent();
//查询目标图层并且把结果存入DataTable
//查询语句
spatialfilter.WhereClause = " CommuName LIKE '" + Input + "%'";//这个CommuName 字段改成自己数据中的字段即可

System.Data.DataTable datatable = qfunc.Query(null,lids[layer_index],spatialfilter);

//组成显示内容
for (int i = 0; i < datatable.Rows.Count; i++)
{
string idv = datatable.Rows[i]["FID"].ToString();


string namev = datatable.Rows[i]["CommuName"].ToString();

if (i == 0)
{
str = "<a href='#' onclick=gocenger('" + idv + "')>" + namev + "</a>";
}
else
{
str = str + "<br/>" + "<a href='#' onclick=gocenger('" + idv + "')>" + namev + "</a>";
}

}

//重新获得Map1控件所有的 functionality
IEnumerable gfc = Map1.GetFunctionalities();
ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource gResource = null;
foreach (IGISFunctionality gfunc in gfc)
{
//找到名为"Selection"的MapResource
if (gfunc.Resource.Name == "Selection")
{
//down cast到 ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource
gResource = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)gfunc.Resource;
}
}

if (gResource == null)
return null;

ESRI.ArcGIS.ADF.Web.display.Graphics.ElementGraphicslayer glayer = null;

foreach (System.Data.DataTable dt in gResource.Graphics.Tables)
{
if (dt is ESRI.ArcGIS.ADF.Web.display.Graphics.ElementGraphicslayer)
{
glayer = (ESRI.ArcGIS.ADF.Web.display.Graphics.ElementGraphicslayer)dt;
break;
}
}

if (glayer == null)
{
glayer = new ESRI.ArcGIS.ADF.Web.display.Graphics.ElementGraphicslayer();

gResource.Graphics.Tables.Add(glayer);
}

//清除已有数据
glayer.Clear();

DaTarowCollection drs = datatable.Rows;

int shpind = -1;
for (int i = 0; i < datatable.Columns.Count; i++)
{
if (datatable.Columns[i].DataType == typeof(ESRI.ArcGIS.ADF.Web.Geometry.Geometry))
{
//找到Geometry 字段的序号
shpind = i;
break;
}
}

try
{
foreach (DaTarow dr in drs)
{
ESRI.ArcGIS.ADF.Web.Geometry.Geometry geom = (ESRI.ArcGIS.ADF.Web.Geometry.Geometry)dr[shpind];

//创建一个 GraphicElement
ESRI.ArcGIS.ADF.Web.display.Graphics.GraphicElement ge = null;
ge = new ESRI.ArcGIS.ADF.Web.display.Graphics.GraphicElement(geom,System.Drawing.Color.Red);
ge.Symbol.Transparency = 50.0;

//将 GraphicElement添加到ElementGraphicslayer中
glayer.Add(ge);
Map1.Extent = glayer.FullExtent;
}
}
catch (InvalidCastException ice)
{
throw new Exception("No geometry available in datatable");
}

if (Map1.ImageBlendingMode == ImageBlendingMode.WebTier)
{
Map1.Refresh();

}
else if (Map1.ImageBlendingMode == ImageBlendingMode.browser)
{
//只刷新Graphics Resource
Map1.RefreshResource(gResource.Name);
}


int n = datatable.Rows.Count;
if (n < 1)
{
str = "<a href='#' onclick=gocenger('" + 0 + "')>" + "找不到相关记录!" + "</a>";

sb.AppendFormat("div:::{0}:::innercontent:::{1}","list1",str);

// this.ListBox1.Items.Add(new ListItem("找不到相关记录"));

v = sb.ToString();

return v;

}


}

sb.AppendFormat("div:::{0}:::innercontent:::{1}",str); //查询到的结果就是显示在list1中的

v = sb.ToString();

return v; //将查询到的结果及显示方式传回到客户端


}


else if (keyvalColl["Type"].ToString() == "queryC")//这个if语句用来实现查询结果在地图上定位的
{

System.Text.StringBuilder sb = new System.Text.StringBuilder();
string Input = keyvalColl["EventArg"];
string str = "";


string targetlayername = "社区";

//获取Data Layers的MapFunctionality
ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)Map1.GetFunctionality(1);
ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = mf.Resource;
//是否支持QueryFunctionality
bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
if (supported)
{
//创建QueryFunctionality
ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality),out lnames);

int layer_index = 0;
//获取目标图层的index
for (int i = 0; i < lnames.Length; i++)
{
if (lnames[i] == targetlayername)
{
layer_index = i;
break;
}

}
//空间过滤
ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter();
//是否返回地理元素
spatialfilter.ReturnADFGeometries = false;
//返回最大记录数
spatialfilter.MaxRecords = 1000;
spatialfilter.Geometry = Map1.GetFullExtent();
//查询目标图层并且把结果存入DataTable
//查询语句

spatialfilter.WhereClause = " CommuName LIKE '" + Input + "%'";

System.Data.DataTable datatable = qfunc.Query(null,spatialfilter);

//重新获得Map1控件所有的 functionality
IEnumerable gfc = Map1.GetFunctionalities();
ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource gResource = null;
foreach (IGISFunctionality gfunc in gfc)
{
//找到名为"Selection"的MapResource
if (gfunc.Resource.Name == "Selection")
{
//down cast到 ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource
//将查询到的结果存到"Selection"的MapResource中
gResource = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)gfunc.Resource;

}
}

if (gResource == null)
return null;

ESRI.ArcGIS.ADF.Web.display.Graphics.ElementGraphicslayer glayer = null;

foreach (System.Data.DataTable dt in gResource.Graphics.Tables)
{
if (dt is ESRI.ArcGIS.ADF.Web.display.Graphics.ElementGraphicslayer)
{
glayer = (ESRI.ArcGIS.ADF.Web.display.Graphics.ElementGraphicslayer)dt;
break;
}
}

if (glayer == null)
{
glayer = new ESRI.ArcGIS.ADF.Web.display.Graphics.ElementGraphicslayer();

gResource.Graphics.Tables.Add(glayer);
}

//清除已有数据
glayer.Clear();

DaTarowCollection drs = datatable.Rows;

int shpind = -1;
for (int i = 0; i < datatable.Columns.Count; i++)
{
if (datatable.Columns[i].DataType == typeof(ESRI.ArcGIS.ADF.Web.Geometry.Geometry))
{
//找到Geometry 字段的序号
shpind = i;
break;
}
}

try
{
foreach (DaTarow dr in drs)
{
ESRI.ArcGIS.ADF.Web.Geometry.Geometry geom = (ESRI.ArcGIS.ADF.Web.Geometry.Geometry)dr[shpind];

//创建一个 GraphicElement
ESRI.ArcGIS.ADF.Web.display.Graphics.GraphicElement ge = null;
ge = new ESRI.ArcGIS.ADF.Web.display.Graphics.GraphicElement(geom,System.Drawing.Color.Red);
ge.Symbol.Transparency = 50.0;

//将 GraphicElement添加到ElementGraphicslayer中
glayer.Add(ge);
Map1.Extent = glayer.FullExtent;//将地图的显示范围该变为查询结果要素的范围

//若是查询到的结果为点,上面这句话要改成以下这段语句:

//double x1 =glayer.FullExtent.XMax+25;
// double x2=glayer.FullExtent.XMin-25;
//double y1= glayer.FullExtent.YMax+25;
// double y2=glayer.FullExtent.YMin-25;
// ESRI.ArcGIS.ADF.Web.Geometry.Envelope pEnv = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope();
// pEnv.XMin =x2;
// pEnv.XMax = x1;
// pEnv.YMin=y2;
// pEnv.YMax = y1;

//Map1.Extent =pEnv.Expand(1);


}
}
catch (InvalidCastException ice)
{
throw new Exception("No geometry available in datatable");
}

if (Map1.ImageBlendingMode == ImageBlendingMode.WebTier)
{
Map1.Refresh();

}
else if (Map1.ImageBlendingMode == ImageBlendingMode.browser)
{
//只刷新Graphics Resource
Map1.RefreshResource(gResource.Name);
}



}


v = Map1.CallbackResults.ToString();

return v; //返回了查询结果显示的内容及其显示范围


}

3、好了,大体上就是这些步骤,2中有很多的注释看起来有点乱,但是一般是写在代码的对应地方,我觉得这样可能易于理解,请见谅!

本文中例子的版权属于千秋一统哦!

ArcGIS Server 中的 Ajax技术的实现举例说明的更多相关文章

  1. 应用程序关闭时的iOS任务

    我正在构建一个应用程序,通过ajax将文件上传到服务器.问题是用户很可能有时不会有互联网连接,并且客户希望在用户重新连接时安排ajax调用.这可能是用户在离线时安排文件上传并关闭应用程序.应用程序关闭时可以进行ajax调用吗?

  2. swift3.0-第一篇tableView

    最近这个月估计要一直设计新的项目天天开会苦不堪言啊~新的项目要用swift来写,从零开始还是很有乐趣的,简单总结了下table的使用,一起学习下吧。直接上代码了感谢观看,学以致用更感谢哦~

  3. android – Phonegap本地构建 – jquery ajax错误:readystate 0 responsetext status 0 statustext error

    解决方法您是否在索引文件中包含了内容安全元标记?

  4. Ajax简单的异步交互及Ajax原生编写

    一提到异步交互大家就会说ajax,仿佛ajax这个技术已经成为了异步交互的代名词.那下面将研究ajax的核心对象

  5. Ajax跨域问题的解决办法汇总(推荐)

    本文给大家分享多种方法解决Ajax跨域问题,非常不错具有参考借鉴价值,感兴趣的朋友一起学习吧

  6. ajax编写简单的登录页面

    这篇文章主要为大家详细介绍了ajax编写简单登录页面的具体代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  7. ajax从JSP传递对象数组到后台的方法

    今天小编就为大家分享一篇ajax从JSP传递对象数组到后台的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  8. 解决ajax返回验证的时候总是弹出error错误的方法

    这篇文章主要介绍了解决ajax返回验证的时候总是弹出error错误的方法,感兴趣的小伙伴们可以参考一下

  9. 使用AJAX完成用户名是否存在异步校验

    这篇文章主要介绍了使用AJAX完成用户名是否存在异步校验的相关资料,需要的朋友可以参考下

  10. ajax实现无刷新省市县三级联动

    这篇文章主要为大家详细介绍了ajax实现无刷新省市县三级联动的相关资料,利用三层架构实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

随机推荐

  1. xe-ajax-mock 前端虚拟服务

    最新版本见Github,点击查看历史版本基于XEAjax扩展的Mock虚拟服务插件;对于前后端分离的开发模式,ajax+mock使前端不再依赖后端接口开发效率更高。CDN使用script方式安装,XEAjaxMock会定义为全局变量生产环境请使用xe-ajax-mock.min.js,更小的压缩版本,可以带来更快的速度体验。

  2. vue 使用 xe-ajax

    安装完成后自动挂载在vue实例this.$ajaxCDN安装使用script方式安装,VXEAjax会定义为全局变量生产环境请使用vxe-ajax.min.js,更小的压缩版本,可以带来更快的速度体验。cdnjs获取最新版本点击浏览已发布的所有npm包源码unpkg获取最新版本点击浏览已发布的所有npm包源码AMD安装require.js安装示例ES6Module安装通过Vue.use()来全局安装示例./Home.vue

  3. AJAX POST数据中文乱码解决

    前端使用encodeURI进行编码后台java.net.URLDecoder进行解码编解码工具

  4. Koa2框架利用CORS完成跨域ajax请求

    实现跨域ajax请求的方式有很多,其中一个是利用CORS,而这个方法关键是在服务器端进行配置。本文仅对能够完成正常跨域ajax响应的,最基本的配置进行说明。这样OPTIONS请求就能够通过了。至此为止,相当于仅仅完成了预检,还没发送真正的请求呢。

  5. form提交时,ajax上传文件并更新到&lt;input&gt;中的value字段

  6. ajax的cache作用

    filePath="+escape;},error:{alert;}});解决方案:1.加cache:false2.url加随机数正常代码:网上高人解读:cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取。

  7. 浅谈ajax上传文件属性contentType = false

    默认值为contentType="application/x-www-form-urlencoded".在默认情况下,内容编码类型满足大多数情况。在这里,我们主要谈谈contentType=false.在使用ajax上传文件时:在其中先封装了一个formData对象,然后使用post方法将文件传给服务器。说到这,我们发现在JQueryajax()方法中我们使contentType=false,这不是冲突了吗?这就是因为当我们在form标签中设置了enctype=“multipart/form-data”,

  8. 909422229_ajaxFileUpload上传文件

    ajaxFileUpload.js很多同名的,因为做出来一个很容易。我上github搜AjaxFileUpload出来很多类似js。ajaxFileUpload是一个异步上传文件的jQuery插件传一个不知道什么版本的上来,以后不用到处找了。语法:$.ajaxFileUploadoptions参数说明:1、url上传处理程序地址。2,fileElementId需要上传的文件域的ID,即的ID。3,secureuri是否启用安全提交,默认为false。4,dataType服务器返回的数据类型。6,error

  9. AJAX-Cache:一款好用的Ajax缓存插件

    原文链接AJAX-Cache是什么Ajax是前端开发必不可少的数据获取手段,在频繁的异步请求业务中,我们往往需要利用“缓存”提升界面响应速度,减少网络资源占用。AJAX-Cache是一款jQuery缓存插件,可以为$.ajax()方法扩展缓存功能。

  10. jsf – Ajax update/render在已渲染属性的组件上不起作用

    我试图ajax更新一个有条件渲染的组件。我可以确保#{user}实际上是可用的。这是怎么引起的,我该如何解决呢?必须始终在ajax可以重新呈现之前呈现组件。Ajax正在使用JavaScriptdocument.getElementById()来查找需要更新的组件。但是如果JSF没有将组件放在第一位,那么JavaScript找不到要更新的内容。解决方案是简单地引用总是渲染的父组件。

返回
顶部