UpdatePanel觸發javascript指令碼的方法附代碼

來源:互聯網
上載者:User

一.預呈現資料無法更改

  1.大家知道,預呈現的資料是無法更改的,以前可能提到過,這裡再看demo,自訂一個控制項

[DefaultProperty("Text")]
[ToolboxData("<{0}:JsControl runat=server></{0}:JsControl>")]
public class JsControl : WebControl
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
 public string Text
 {
 get
 {
 String s = (String)ViewState["Text"];
 return ((s == null) ? String.Empty : s);
 }

  set
 {
  ViewState["Text"] = value;
  }
}

 protected override void OnPreRender(EventArgs e)
 {
 Text = "hello,you can't change me";
 base.OnPreRender(e);
 }

 protected override void RenderContents(HtmlTextWriter output)
 {
 output.Write(Text);
 }
}
aspx頁面

protected void Button1_Click(object sender, EventArgs e)
{
JsControl1.Text = "I want to change the Text property";
}
  你會發現你並未更改屬性.這牽涉到控制項生命週期的執行.為什麼要說這個,因為控制項的大部分指令碼都是在預呈現中註冊的.

  這有什麼問題嗎? 其本身想法很好,指令碼在此事件(指OnPreRender)中註冊,註冊指令碼資源在前(控制項夾中間),指令碼初始化在最後.這符合javascript的使用原則,先匯入指令碼,然後有標籤,初始化的指令碼須放在標籤後面.

  二.UpdatePanel引起的問題

  上面的問題如果是伺服器提交回傳的則可行,主要問題是我們要用ajax無重新整理註冊指令碼.以下我們再來看asp.net2.0內建的treeview控制項,拖個控制項要頁面看其產生的html代碼。

  你已經看到很多的指令碼註冊和初始化了.

  我們來測試下UpdatePanel能幹什麼事情,我們設定其屬性Visible為False到True

  藉助FireBug的威力我們來看下UpdatePanel在無重新整理狀態下返回給了我們什麼
 
  出錯了,大家可能也遇到過此情況,很正常嘛,UpdatePanel沒有為我們註冊指令碼也沒未我們初始化,在屬於正常現象,UpdatePanel只管其容器裡面的,其他的不歸它管.

  三.解決方案

  要解決TreeView控制項,我是想不出來,這個控制項算是在asp.net ajax模式下算是完蛋了.為了迎合asp.net ajax架構的運用,我們需要知道UpdatePanel無重新整理修改範圍,當我們自己定義控制項的時候就需要注意.

1.控制項本身標籤
2.控制項內部
3.UpdatePanel容器內部

  若想使用UpdatePanel更新資料後再觸發用戶端事件的,有以下方案

  1.通過更改現有控制項屬性,如

Button1.Attributes["onmouseover"] = "alert('hello')";
  2.在呈現過程中指令碼初始化

  第一種方法簡單運用還可以,複雜就不行了,我們還是需要把指令碼封裝好跟控制項結合使用的,我們不再在預呈現中註冊指令碼,而在呈現中實現(即RederContent方法).
我們只要保證指令碼資源在前,初始化在後,控制項在中間這一原則就可以了...以下方法是可行的

如下
protected override void RenderContents(HtmlTextWriter output)
{
output.Write("<script src=\"xxxx.js\"></script>");
output.Write(Text);
output.Write("<script>alert('hello')</script>");
}
  四.幾個誤區

  1.驗證控制項在ajax架構中可以完好使用
其實是其載入了一段指令碼,不然其也會掛掉
  2.狀態保留
  在UpdatePanel中更新資料後,再Postback,無重新整理更新的資料狀態還保留
  3.更新資料後執行用戶端指令碼

曾經我們天真的會這麼寫

protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "alert('hello')";
}
  結果什麼也沒發生,window.onload事件已過,除非你重新整理(可你不想重新整理),不然沒人幫你觸發。
  誰來觸發?微軟幫我們準備好了。你要的大概就是這個了,資料更新前後都是一個事件觸發。我們可以圍繞著這兩個事件為控制項做點事情。這個狀態適合於資料取到後就立馬觸發的需要。
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
 Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
 function BeginRequestHandler(sender, args)
 {
 var elem = args.get_postBackElement();
 ActivateAlertDiv('visible', 'AlertDiv', elem.value + ' processing');
 }
 function EndRequestHandler(sender, args)
 {
 ActivateAlertDiv('hidden', 'AlertDiv', '');
 }
 function ActivateAlertDiv(visstring, elem, msg)
 {
 var adiv = $get(elem);
 adiv.style.visibility = visstring;
 adiv.innerHTML = msg;
 }
  其他的話我們也可以更改控制項屬性,就如加個onclick事件什麼的都可以

  五.另類解決方案

此方法比較的絕,但用起來比較的爽。UpdatePanel之所以無法擷取到指令碼資料,是因為其擷取範圍還不夠。。。接著的想法是:

  照樣無重新整理取資料,但取回來的資料跟Postback回來的資料一樣。
可能有人說會比較耗效能,那都是相對的。不過也是一個很好的想法。Telerik公司的RadAjaxPanel就是這麼實現的,有興趣的可以下載一個用用

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.