Ajax的一些高级功能的展现

使用Ajax:
1.使用Unicode字符发送反馈.
 这个例子发送一个Form到Server端,调用Server端的Test1方法,并返回一个HTML的字符串.
 
 在Server端有一个标准的方法,附加有一个额外的属性:
 [Ajax.AjaxMethod]
        public string Test1(string firstName, string familyName, string email, string comment)
        {
          string html = "";
         
          html += "Hello " + firstName + " " + familyName + "<br>";
          html += "Thank you for your comment <b>";
          html += System.Web.HttpUtility.HtmlEncode(comment);
          html += "</b>.";
         
          return html;
        }
 
 客户端调用:
 Test1:function(firstName,familyName,email,comment,callback,context){
 return new ajax_request(this.url + '?_method=Test1&_session=no',
  'firstName=' + enc(firstName)+ '\r\nfamilyName=' +
  enc(familyName)+ '\r\nemail=' + enc(email)+ '\r\ncomment=' + enc(comment),
  callback,
  context); 
 
 其中callback定义对返回结果的处理.

2.使用自定义的类型为参数:发送一个真正的.net对象到Server端处理.

 Client端调用:
 var d = new DateTime(2005,08,30,0,0,0);
 DemoMethods.Test2(d,callback);

 Server端:
 [Ajax.AjaxMethod]
 public string Test2(DateTime d)
 {
 d = d.AddDays(1);
 return "The next day will be " + d.ToLongDateString() + ".";
 }
 
 目前已经做了类型转化的有:(要实现类型转换的兼容,IAjaxObjectConverters是必要的接口)
 - System.Collections.ArrayList
 - System.Data.DataSet/DataTable/DataRow
 - System.DateTime/TimeSpan
 - System.Array

3.使用System.Data.DataSet对象来填充下拉框
 Client端调用,当Server端返回一个DataSet时,我们的callback函数这么写:(把其中的res.value当作DataSet处理)
 function callback(res)
 {
  var html = []; 
  for(var i=0; i<res.value.Tables[0].Rows.length; i++)
   html[html.length] = "<option>" + res.value.Tables[0].Rows[i].Country + "</option>";

  document.getElementById("display").innerHTML = "<select id=\"sel\">" + html.join("") + "</select>";
 }

4.注意处理Server端产生的Ajax异常:返回值的error.
 如果Server端产生了Ajax异常,那么我们在处理返回值的时候可以加以识别,callback函数:
 function callback(res)
 {
  if(res.error != null){
   alert(res.error); //处理错误的方法
  }
 }

5.存取SessionState,对于SessionState访问需要AjaxMethod方法带有HttpSessionStateRequirement.ReadWrite的参数说明
例如Server端:
 [Ajax.AjaxMethod(HttpSessionStateRequirement.ReadWrite)]
 public void Test5(string value)
 {
  System.Web.HttpContext.Current.Session["example"] = value;
 }

 [Ajax.AjaxMethod(HttpSessionStateRequirement.Read)]
 public string Test6()
 {
  if(System.Web.HttpContext.Current.Session["example"] != null)
   return (string)System.Web.HttpContext.Current.Session["test"];
  return "First set the value...";
 }

6.一次请求的处理进行中,耗费时间较长,但并不影响其他请求或操作的进行.他们可以是同步进行的.
 [Ajax.AjaxMethod]
 public void Test7()
 {
  int c = 0;
  do
  {
   System.Threading.Thread.Sleep(1000);
   c++;
  }while(c < 10);
 }
 当该请求完成的时候,他会触发回调callback函数的执行,所以不会引起network tracffic的发生.

显然,这个请求需要耗费10秒,但是他的处理并不影响别的请求的进行,客户端并不会等待,而是同步进行别的活动.


7.在Client端使用Context,利用context存储一定的信息:
 <script language="javascript">
 function test8(ele)
 {
  DemoMethods.Test8(test8_callback, ele);  // the server-side method has no arguments!
 }

 function test8_callback(res)
 {
  if(res.error == null && res.context != null)
  res.context.innerHTML = res.value;
 }
 </script>

 <span onclick="test8(this);">Element1</span>
 <span onclick="test8(this);">Element2</span>
 
 在这个例子中,我们就把span区域的对象作为请求的context传给请求函数,当回调callback函数接受结果时,结果中也包含这个context,
 因此可以方便把值设给它.

8.从Server端返回数组&System.Collections.ICollection对象.
 [Ajax.AjaxMethod]
 public System.Collections.Specialized.StringCollection Test9()
 {
  System.Collections.Specialized.StringCollection s = new System.Collections.Specialized.StringCollection();
  s.Add("Michael");
  s.Add("Hans");
  return s;
 }
 
 [Ajax.AjaxMethod]
 public object[] Test10()
 {
  object[] o = new object[3];
  o[0] = "Michael";
  o[1] = DateTime.Now;
  o[2] = true;
  return o;
 }

 当然实现了ICollection接口的类都是可以的,比如ArrayList,这时我们在Client端存取的方法:
 
 function test11_callback(res)
 {
  if(res.value[2])                           // bolean
  alert(res.value[1].toLocaleString());    // date

  alert(res.value[3].FirstName + " + " + res.value[4].FirstName);
 }
 
 也就是说返回的value是一个数组,我们通过[]的方法存取.

9.增加自己扩展的支持类型,需要实现IAjaxObjectConverters,增到系统中,需要修改web.config文件,
在ajaxConverters中用add项增加Converter,用remove项删除已有的Converter:

<configuration>
  <configSections>
    <sectionGroup name="ajaxNet">
      <section name="ajaxSettings" type="Ajax.AjaxSettingsSectionHandler, Ajax" />
      <section name="ajaxConverters" type="Ajax.AjaxConverterSectionHandler, Ajax" />
    </sectionGroup>
  </configSections>

  <ajaxNet>
    <ajaxConverters>
      <add type="Namespace.Class1, Assembly" />
      <remove type="Ajax.JSON.DataSetConverter, Ajax" >
    </ajaxConverters>
  </ajaxNet>
</configuration>


10.从Server端返回自定义的类对象,这个对象需要申明为Serializable的,而在Client端对它的操作和在Server端的操作是一样的:
Server:
 [Serializable]
 public class Person
 {
  public string FirstName;
  public string FamilyName;
  public int Age = 0;
  public Person NewChild()
  {
   Person p = new Person();
   p.FamilyName = FamilyName;
      return p;
  }

  public Person[] Children = null;
 }

Client处理返回回来的Person对象:
 function test12_callback(res)
 {
  var s = res.value.FirstName + " " + res.value.FamilyName + ":\r\n";
  for(var i=0; i<res.value.Children.length; i++)
   s += "\t" + res.value.Children[i].FirstName + "\r\n";
  alert(s);
 }

11.返回一个图片:
 Server端:
 [Ajax.AjaxMethod]
 public System.Drawing.Bitmap Test16()
 {
  Bitmap bmp = new Bitmap(200, 50);
  Graphics g = Graphics.FromImage(bmp);
  g.FillRectangle(new SolidBrush(Color.Yellow), 0, 0, 199, 49);
  g.DrawString(DateTime.Now.ToString(), new Font("Arial", 10), new SolidBrush(Color.Red), 10, 10);
  return bmp;
 }

 Client端:
 function test16_callback(res)
 {
  if(typeof(res.value) == 'object')
   document.getElementById("imageholder").appendChild(res.value);
 }

 其中imageholder是一个div标签区域.


12.使用数组作为参数:
 在Server端有Ajax方法:
 [Ajax.AjaxMethod]
 public string Test18(string[] s)
 {
  string r = "";
  foreach(string ss in s)
  r += "<p>" + ss + "</p>\r\n";
  return r;
 }

 在Client端可以这样调用:
 alert(DemoMethods.Test18( ["aaaa","bbbb","ccc\"ccccc"] ).value);

 同时也支持int[],其他的类型慢慢也会加入到Ajax中来

13.传递HtmlControl到Server端,处理完了并返回.
 Server端返回一个新建的HtmlSelect:
 [Ajax.AjaxMethod]
 public System.Web.UI.HtmlControls.HtmlSelect Test19(string car)
 {
  System.Web.UI.HtmlControls.HtmlSelect control = new System.Web.UI.HtmlControls.HtmlSelect();
  switch(car)
  {
   case "VW":
   control.Items.Add("Golf");
   control.Items.Add("Passat");
   control.Items.Add("Beetle");
   control.Items.Add("Phaeton");
   break;
   
   case "Mercedes":
   control.Items.Add("S Class");
   control.Items.Add("E Class");
   control.Items.Add("A Class");
   control.Items.Add("M Class");
   break;

   case "Citroen":
   control.Items.Add("C3 Pluriel");
   control.Items.Add("C5 Break");
   control.Items.Add("C8");
   control.Items.Add("Berlingo");
   break;
  }
  return control;
 }

 客户端接受到这个控件,并放在一个Span区域内(id='ele'):
 var res = Test19("VW");
 var ele = document.getElementById('ele');
 ele.innerHTML = res.value;

 完成了从server端接受一个Html控件的过程,对于所有的HtmlControls亦是如此.

14.缓存请求,以节约CPU时间:
 对于某些频繁的请求,如果缓存下来的结果也满足要求的话,那么缓存结果将使得CPU时间得到节约.
 要缓存很简单,只需要在Server的方法上加上缓存时间就可以,缓存时间以秒为单位(sec):
 [Ajax.AjaxMethod(30)]
 public System.DateTime Test20()
 {
  return DateTime.Now;
 }

 在第一次请求后的30秒内,任何的请求结果都是第一次请求的缓存.

posted @ 2006-10-26 09:57  '.Elvis.'  阅读(327)  评论(0)    收藏  举报