ASP.NET 2.0 的 Client Script Callback
ASP.NET 2.0 的 Client Script Callback 的确很垃圾,准备彻底抛弃不用了,在把自己的代码删除以前,先在这里贴一下,留个备份:
一页一个callback的例子比较简单,下面是一个同一页内多个callback的例子,我们需要建立一个control class,然后把callback handler 分别 delegate 给它:
1 public CustomerControls.ClientCallbackControl
2 YearCallbackControl = new CustomerControls.ClientCallbackControl(),
3 MakeCallbackControl = new CustomerControls.ClientCallbackControl();
4
5 protected void Page_Load(object sender, EventArgs e)
6 {
7 this.VehicleManager = new VehicleManager(this.Page.WMagic);
8
9 this.YearCallbackControl.ClientCallback += new CustomerControls.ClientCallbackDelegate(YearOrMakeCallbackControl_ClientCallback);
10 this.AddParsedSubObject(this.YearCallbackControl);
11 this.year.Attributes["onchange"] += Page.ClientScript.GetCallbackEventReference(
12 this.YearCallbackControl,
13 "this.value+','+" + this.make.ClientID.Replace("_", "$") + ".value",
14 "FillDropDownList",
15 "'" + this.model.ClientID + "'",
16 false);
17
18 this.MakeCallbackControl.ClientCallback += new CustomerControls.ClientCallbackDelegate(YearOrMakeCallbackControl_ClientCallback);
19 this.AddParsedSubObject(this.MakeCallbackControl);
20 this.make.Attributes["onchange"] += Page.ClientScript.GetCallbackEventReference(
21 this.MakeCallbackControl,
22 this.year.ClientID.Replace("_", "$") + ".value+','+this.value",
23 "FillDropDownList",
24 "'" + this.model.ClientID + "'",
25 false);
26
27 if (!this.IsPostBack)
28 {
29 foreach (int year in this.VehicleManager.GetYears())
30 this.year.Items.Add(new ListItem("" + year, "" + year));
31
32 this.make.DataSource = this.VehicleManager.GetMakes();
33 this.make.DataTextField = "Key";
34 this.make.DataValueField = "Value";
35 this.make.DataBind();
36 }
37 }
38
39 string YearOrMakeCallbackControl_ClientCallback(string eventAgrument)
40 {
41 string result = "";
42 string[] agruments = eventAgrument.Split(new char[] {','});
43 int year = Util.TryInt(agruments[0]);
44 int make = Util.TryInt(agruments[1]);
45 if (year == 0 || make == 0) return "[]";
46
47 foreach (KeyValuePair<string, int> model in this.VehicleManager.GetModels(year, make))
48 result += ",['" + model.Key + "'," + model.Value + "]";
49 result = (result.StartsWith(",")) ? result.Substring(1) : "";
50
51 return "[" + result.Replace("'", "\\'").Replace("\"", """) + "]";
52 }
53
2 YearCallbackControl = new CustomerControls.ClientCallbackControl(),
3 MakeCallbackControl = new CustomerControls.ClientCallbackControl();
4
5 protected void Page_Load(object sender, EventArgs e)
6 {
7 this.VehicleManager = new VehicleManager(this.Page.WMagic);
8
9 this.YearCallbackControl.ClientCallback += new CustomerControls.ClientCallbackDelegate(YearOrMakeCallbackControl_ClientCallback);
10 this.AddParsedSubObject(this.YearCallbackControl);
11 this.year.Attributes["onchange"] += Page.ClientScript.GetCallbackEventReference(
12 this.YearCallbackControl,
13 "this.value+','+" + this.make.ClientID.Replace("_", "$") + ".value",
14 "FillDropDownList",
15 "'" + this.model.ClientID + "'",
16 false);
17
18 this.MakeCallbackControl.ClientCallback += new CustomerControls.ClientCallbackDelegate(YearOrMakeCallbackControl_ClientCallback);
19 this.AddParsedSubObject(this.MakeCallbackControl);
20 this.make.Attributes["onchange"] += Page.ClientScript.GetCallbackEventReference(
21 this.MakeCallbackControl,
22 this.year.ClientID.Replace("_", "$") + ".value+','+this.value",
23 "FillDropDownList",
24 "'" + this.model.ClientID + "'",
25 false);
26
27 if (!this.IsPostBack)
28 {
29 foreach (int year in this.VehicleManager.GetYears())
30 this.year.Items.Add(new ListItem("" + year, "" + year));
31
32 this.make.DataSource = this.VehicleManager.GetMakes();
33 this.make.DataTextField = "Key";
34 this.make.DataValueField = "Value";
35 this.make.DataBind();
36 }
37 }
38
39 string YearOrMakeCallbackControl_ClientCallback(string eventAgrument)
40 {
41 string result = "";
42 string[] agruments = eventAgrument.Split(new char[] {','});
43 int year = Util.TryInt(agruments[0]);
44 int make = Util.TryInt(agruments[1]);
45 if (year == 0 || make == 0) return "[]";
46
47 foreach (KeyValuePair<string, int> model in this.VehicleManager.GetModels(year, make))
48 result += ",['" + model.Key + "'," + model.Value + "]";
49 result = (result.StartsWith(",")) ? result.Substring(1) : "";
50
51 return "[" + result.Replace("'", "\\'").Replace("\"", """) + "]";
52 }
53
那个callback control class
1using System;
2
3namespace CustomerControls
4{
5 public delegate string ClientCallbackDelegate(string eventAgrument);
6
7 public class ClientCallbackControl : System.Web.UI.Control, System.Web.UI.ICallbackEventHandler
8 {
9 public event ClientCallbackDelegate ClientCallback;
10
11 string CallbackResult = "";
12
13 ICallbackEventHandler Members
31 }
32}
33
2
3namespace CustomerControls
4{
5 public delegate string ClientCallbackDelegate(string eventAgrument);
6
7 public class ClientCallbackControl : System.Web.UI.Control, System.Web.UI.ICallbackEventHandler
8 {
9 public event ClientCallbackDelegate ClientCallback;
10
11 string CallbackResult = "";
12
13 ICallbackEventHandler Members
31 }
32}
33
网页上的代码:
1function FillDropDownList(result, context)
2{
3 setTimeout("DelayRun(\"" + result + "\", '" + context + "')", 50);
4}
5
6function DelayRun(result, context)
7{
8 eval("var data="+result);
9 var list = document.getElementById(context);
10 if (list!=null)
11 {
12 for (i=list.options.length-1; i>=0; i--) list.remove(i);
13 for (i=0; i<data.length; i++) list.options.add(new Option(data[i][0], data[i][1]));
14 }
15}
2{
3 setTimeout("DelayRun(\"" + result + "\", '" + context + "')", 50);
4}
5
6function DelayRun(result, context)
7{
8 eval("var data="+result);
9 var list = document.getElementById(context);
10 if (list!=null)
11 {
12 for (i=list.options.length-1; i>=0; i--) list.remove(i);
13 for (i=0; i<data.length; i++) list.options.add(new Option(data[i][0], data[i][1]));
14 }
15}
注意:因为asp.net 2.0的一个bug,callback client 端函数必须用一个timeout延迟执行(这只是workaround的方法中的一种),不然也运行,但有一个js错误提示。M$说会在下一个release补上。
altlas又还是beta,真不知道该用什么?
PS:注意网页中 EnableEventValidation="false" 的设置。