使用者控制元件中使用客戶端指令碼的控制元件名稱問題
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
asp.net提供一種很好的模組級的複用技術――使用者控制元件,大大方便了web網站的建設,提高了效率。使用者控制元件使用多了,碰到的問題也會增多。最近遇到一個問題,就是如果在一個使用者控制元件中要使用到客戶端指令碼,而這個客戶端的指令碼又要訪問到控制元件中包含的控制元件,問題就出現了。問題是當一個使用者控制元件被包含到一個aspx頁面後,呈現到使用者客戶端後,整個使用者控制元件中的控制元件的名稱將會有所變化,它們不再是你設計這個使用者控制元件時的名稱,而是有兩個相關的名稱:
id ―― 客戶端可以通過這個id訪問這個客戶端控制元件,asp.net給每個控制元件輸出的id形式為“使用者控制元件id_此控制元件的id”,如果是使用者控制元件巢狀的情況,形式為“頂層使用者控制元件id_下層使用者控制元件id_此控制元件的id”
name――客戶端也可以通過這個name來訪問這個客戶端控制元件,asp.net給每個控制元件輸出的name“使用者控制元件id:此控制元件的id”,如果是使用者控制元件巢狀的情況,形式為“頂層使用者控制元件id:下層使用者控制元件id:此控制元件的id”。
例子:<input name="WebUserControl11:TextBox1" type="text" id="WebUserControl11_TextBox1" />
在設計使用者控制元件時,放置了一個TextBox,id為TexBox1,這個使用者控制元件被放置到一個aspx頁面,使用者控制元件的id為WebUserControl11,最後這個使用者控制元件的TextBox到客戶端後就是上面的這個樣子的了。
客戶端提交到服務端時是根據控制元件的name來提交的,也就是說,對服務端來講,客戶端的name是有意義的,id是不需要的。
在寫客戶端指令碼時你不能預知你的使用者控制元件將會是以什麼id加入到aspx頁面的,也不能預知使用者控制元件被嵌套了多少層,所以你根本不能在設計時來參考這些控制元件。
幸好,asp.net的webcontrol 和 htmlcontrol
所以我們可以用控制元件的UniqueID來獲得執行時客戶端的name,也就能通過這個name來控制客戶端控制元件了。
OK,按照這個思路來設計個客戶端指令碼:
使用者控制元件很簡單,就放置一個TextBox,我們再給這個TextBox設定一個滑鼠經過事件來觸犯客戶端的指令碼,給TextBox賦一個值,程式碼如下:
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="WebUserControl1.ascx.cs" Inherits="WebApplication3.WebUserControl1" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> <asp:TextBox id="TextBox1" runat="server" onmouseover="over()"></asp:TextBox> <script language=javascript> <!-- function over() { document.all.<%= TextBox1.UniqueID%>.value = "kent"; } //--> </script> |
將這個使用者控制元件拖放到一個aspx頁面中,編譯瀏覽這個頁面,報一個指令碼錯誤:缺少‘;’
把滑鼠移到TextBox時,又報一個指令碼錯誤:“缺少物件”
檢查發現,客戶端引用的標示不能含有”:”符號,就是說在客戶端不能用控制元件的name來參考。asp.net的webcontrol 和 htmlcontrol 的控制元件還有個執行時屬性 ClientID,它用來獲取由 ASP.NET 生成的伺服器控制元件識別符號,也就是來獲取控制元件的客戶端id的,我們再改用這個屬性來試一下:
document.all.<%= TextBox1.ClientID %>.value = "kent";
再執行,OK成功,當滑鼠移動TextBox時,TextBox中出現了“kent”。