官术网_书友最值得收藏!

  • 決戰(zhàn).NET
  • 黃忠成
  • 1659字
  • 2018-12-27 16:55:59

3.8 包含外部的JavaScript文件

理論上,UpdatePanel控件中可放入大部分的ASP.NET控件,這也包含了使用者自定義的UserControl控件,但是這有個(gè)異常情況,當(dāng)該UserControl中含有JavaScript程序代碼,且被動(dòng)態(tài)加載至UpdatePanel控件中時(shí)會(huì)引發(fā)一些問(wèn)題。呃!動(dòng)態(tài)加載UserControl至UpdatePanel中,這不是跟前面提及的動(dòng)態(tài)加載控件一樣嗎?不過(guò)這次我們采用另一種方式,用完全式的動(dòng)態(tài)加載,也就是說(shuō)一開(kāi)始UserControl并不是放在UpdatePanel控件中的,而是在使用者點(diǎn)擊按鈕后,由程序動(dòng)態(tài)加載的。請(qǐng)照以下的步驟來(lái)創(chuàng)建一個(gè)新網(wǎng)頁(yè)。

1. 創(chuàng)建一個(gè)UserControl,取名為WebUserControl.ascx,程序代碼如程序3-18所示。

2. 創(chuàng)建一個(gè)新網(wǎng)頁(yè),命名為UseUserControl.aspx。

3. 在頁(yè)面中放入ScriptManager控件。

4. 在頁(yè)面中放入U(xiǎn)pdatePanel控件。

5. 將UpdatePanel1控件的UpdateMode設(shè)為Conditional。

6. 放此WebUserControl控件至UpdatePanel控件中。

程序3-18

    Samples\3\AjaxDemo1\WebUserControl.ascx
    <%@ Control Language="C#" AutoEventWireup="true" CodeFile=
      "WebUserControl.ascx.cs" Inherits="WebUserControl" %>
    <script language=javascript>
      function showMessage(msg)
      {
          alert('Message:'+msg);
      }
    </script>
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click"
    OnClientClick="showMessage('Test')" />

運(yùn)行程序后,點(diǎn)擊Button后便可看到信息,如圖3-15所示。

true

圖3-15

這個(gè)例子證明了UserControl可以放在UpdatePanel控件中,接下來(lái)就是將此例子改成動(dòng)態(tài)加載UserControl。請(qǐng)照以下步驟做。

1. 創(chuàng)建一個(gè)新網(wǎng)頁(yè),命名為DynamicLoadUserControl1.aspx。

2. 在頁(yè)面中放入一個(gè)ScriptManager控件。

3. 在頁(yè)面中放入一個(gè)UpdatePanel控件。

4. 放一個(gè)Button控件至UpdatePanel控件中。

5. 在Button的Click事件中鍵入程序3-19的代碼。

程序3-19

    Samples\3\DynamicLoadUserControl1.aspx
    protected void Button1_Click(object sender, EventArgs e)
    {
            if (UpdatePanel1.ContentTemplateContainer.FindControl("DynamicControl1")
                == null)
            {
                  Control c = Page.LoadControl("WebUserControl.ascx");
                  c.ID = "DynamicControl1";
                  UpdatePanel1.ContentTemplateContainer.Controls.Add(c);
            }
    }

運(yùn)行程序并點(diǎn)擊Button后,便可看到該UserControl控件已被載入,這是無(wú)刷新動(dòng)態(tài)加載UserControl的基礎(chǔ),如圖3-16所示。

true

圖3-16

但若點(diǎn)擊右方的Button后,會(huì)看到報(bào)錯(cuò)信息,如圖3-17所示。

true

圖3-17

這是為什么呢?是因?yàn)閁pdatePanel控件的處理機(jī)制。只要異步刷新的內(nèi)容含有JavaScript程序代碼,這段程序代碼是無(wú)法被繪制到現(xiàn)行網(wǎng)頁(yè)中的。別誤會(huì)!我指的是明白聲明成<script>...</script>的程序代碼,以及<script src....></script>類的程序代碼,不包含直接于HTML元素中所設(shè)定的程序代碼,例如onclick='alert(...)'類的程序代碼是被允許的,但是若這類程序代碼調(diào)用其他自定義于以上兩種區(qū)段的函數(shù)時(shí),同樣是行不通的!就如同本例中,showMessage是聲明于<script>區(qū)段中的,雖然onclick可以正常繪制,但因?yàn)樗{(diào)用的JavaScript函數(shù)未被繪制,所以引發(fā)調(diào)用函數(shù)不存在的錯(cuò)誤。這個(gè)特性也告訴了我們,UpdatePanel控件中所能動(dòng)態(tài)加載的ASP.NET控件類型,只要該ASP.NET控件會(huì)輸出以上兩種區(qū)段JavaScript程序代碼的,便會(huì)引發(fā)錯(cuò)誤,典型的控件便是TreeView!那這該如何解決呢?這得視欲載入的控件而定了。TreeView控件是很難從外部修改,令其可動(dòng)態(tài)加載至UpdatePanel中的,不過(guò)我們的UserControl沒(méi)那么復(fù)雜,只要運(yùn)用ScriptManager控件的Scripts屬性,加載指定的JavaScript程序文件即可。請(qǐng)照著下面的步驟做。

1. 創(chuàng)建一個(gè)新網(wǎng)頁(yè),命名為DynamicLoadUserControl2.aspx。

2. 在頁(yè)面中放入一個(gè)ScriptManager控件。

3. 在頁(yè)面中放入一個(gè)UpdatePanel控件。

4. 放一個(gè)Button控件至UpdatePanel控件中。

5. 在Button的Click事件中鍵入程序3-20的代碼。

6. 創(chuàng)建一個(gè)UserControl,命名為WebUserControl1.ascx,內(nèi)容如程序3-21所示。

7. 創(chuàng)建一個(gè)JavaScript文件,命名為JScript.js,內(nèi)容如程序3-22所示。

8. 點(diǎn)擊ScriptManager控件的Scripts屬性,加入引用JScript.js文件,如圖3-18所示。

程序3-20

    Samples\3\DynamicLoadUserControl1.aspx
    protected void Button1_Click(object sender, EventArgs e)
    {
            if (UpdatePanel1.ContentTemplateContainer.FindControl("DynamicControl1")
                == null)
            {
                Control c = Page.LoadControl("WebUserControl1.ascx");
                c.ID = "DynamicControl1";
                UpdatePanel1.ContentTemplateContainer.Controls.Add(c);
            }
    }

程序3-21

    Samples\3\AjaxDemo1\WebUserControl1.ascx
    <%@ Control Language="C#" AutoEventWireup="true" CodeFile=
      "WebUserControl1.ascx.cs" Inherits="WebUserControl1" %>
    </script>
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click"
    OnClientClick="showMessage('Test')" />

程序3-22

    function showMessage(str)
    {
      alert(str);
    }
    //很重要,所有通過(guò)ScriptReference并以Path方式加載的.js文件中都必須包含這段程序代碼,
    //告訴ASP.NET AJAX這個(gè).js已經(jīng)完全加載完畢.
      if(Sys && Sys.Application) { Sys.Application.notifyScriptLoaded(); }

在程序3-22 的代碼末行,調(diào)用了Sys.Application.notifyScriptLoaded函數(shù),此舉目的在于告訴ASP.NET AJAX的Script Loader這個(gè)JavaScript程序文件已經(jīng)完全加載完畢。

true

圖3-18

這里的Path指的是JScript.js的位置,若放于其他目錄中,例如scripts目錄中,即設(shè)為“scripts/JScript.js”,指定的文件將會(huì)于此網(wǎng)頁(yè)初次繪制時(shí)便被載入,以本例來(lái)說(shuō),原本動(dòng)態(tài)加載時(shí)是無(wú)法加載JavaScript的,但是只要這樣設(shè)置后,該JavaScript早就已經(jīng)被加載,所以本例便可運(yùn)行了。除了載入真實(shí)的JavaScript文件外,ScriptManager控件也允許加載Assembly中的Script資源,這部分將于后面ASP.NET AJAX延展性一節(jié)中討論。完成并運(yùn)行本例后,便可發(fā)現(xiàn)其已能正常運(yùn)行了,如圖3-19所示。

true

圖3-19

Scripts中指定的JavaScript文件的加載位置會(huì)受到ScriptManager之LoadScriptsBeforeUI屬性值影響,默認(rèn)此屬性值為True,也就是于UI控件載入前載入這些Scripts,若此值為False,那么Scripts便會(huì)于UI控件加載后加載,這會(huì)造成什么影響呢?當(dāng)此值為False時(shí),Scripts載入于UI控件加載之后,因此若Script中有全局程序代碼時(shí),且這些程序代碼中企圖以$get函數(shù)取得UI控件的HTML元素對(duì)象時(shí),將可以正常運(yùn)行。反之若此值為True,加載Script時(shí)UI控件尚未完全加載,所以在全局程序代碼中調(diào)用$get函數(shù)時(shí)便會(huì)回傳NULL。舉個(gè)較實(shí)際的例子,若將程序3-22改成如程序3-23,那么在LoadScriptsBeforeUI值為True時(shí)會(huì)產(chǎn)生錯(cuò)誤,為False則不會(huì)。

程序3-23

    function showMessage(str)
    {
      alert(str);
    }
    var p = $get('Button1').value;
    //for every script include at scriptReference with path of ScriptManager/
      ScriptManagerProxy,
    //you must add below code to notify Script is loaded,or you may get Sys.
      ScriptLoadFailedException Exception;.
    //if your scriptReference is with Assembly,you can set NotifyScriptLoaded to
      true,
    //ScriptManager will add notifyScriptLoaded code for your script code.
    if(Sys && Sys.Application) { Sys.Application.notifyScriptLoaded(); }
主站蜘蛛池模板: 永善县| 广平县| 绥芬河市| 鹿泉市| 象山县| 拉萨市| 黑龙江省| 通许县| 桂阳县| 大悟县| 汤阴县| 新泰市| 珠海市| 遂宁市| 章丘市| 颍上县| 阜平县| 阳泉市| 车致| 天水市| 兴宁市| 集贤县| 印江| 永昌县| 安吉县| 梨树县| 富川| 汪清县| 衡阳市| 灵丘县| 威信县| 无极县| 绍兴县| 华安县| 刚察县| 通化市| 南汇区| 安阳市| 兴仁县| 循化| 武冈市|