国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

ASP.NET 無法確保在注冊的 JavaScript 內不存在重復定義

2019-11-18 16:41:50
字體:
來源:轉載
供稿:網友

asp.net 2.0中,我們使用Page.ClientScript屬性(也就是一個ClientScriptManager對象)的一些名字以Register開頭的方法注冊客戶端腳本,這是大家都知道的。

理論上應該如何避免沖突
先說說為什么要這樣注冊腳本,而不用Response.Write直接輸出。舉個例子,你用3個DropDownList做了一個輸入日期的區域,分別代表年/月/日,然后你為了防止用戶輸入2007/02/31,所以你決定把這3個DropDownList做成級聯的,也就是隨著年和月的輸入改變,日的可選項跟著改變。這時候你可以通過寫一些javaScript來實現級聯,例如定義一個名為updateDateRange()的Javascript函數負責更新DropDownList,然后直接把這些JavaScript放到C#的字符串里,并且使用Response.Write輸出。這些代碼用起來會很正常,直到有一次你的頁面需要輸入兩個日期。

在需要輸入兩個日期的那個頁面上,你把3個DropDownList復制粘貼了一遍,也把輸出的JavaScript的那段代碼復制粘貼了一遍,接著根據兩處ID的不同做了相應的修改,結果有一組級聯無法正常運行起來。你查看服務器端輸出的HTML,接著恍然大悟——原來有兩個updateDateRange()函數。于是你把updateDateRange()改為updateDateRange(yearControlClientId, monthControlClientId, dateControlClientId),同時把JavaScript刪減為僅輸出一遍,這時候無論哪組級聯都使用同一個函數,它們根據調用時輸入的DropDownList.ClientID來區分。

又有一天,你決定把這組級聯封裝為一個UserControl,做起來當然還是復制粘貼大法,也就是把3個DropDownList和JavaScript復制進UserControl,然后把UserControl的引用復制回原本的調用處。忙完之后,發現那個有兩個日期輸入的頁面又出錯了,原來updateDateRange(yearControlClientId, monthControlClientId, dateControlClientId)又被重復輸出了,因為頁面上放入了兩個UserControl所以JavaScript被輸出了兩遍,并且沒辦法減少輸出次數。
'http://m.survivalescaperooms.com
這時候你可以使用Page.ClientScript.RegisterClientScriptBlock解決問題,它通過type和key這兩個參數確定腳本是否被重復注冊,而被重復注冊的腳本僅會輸出一次。為什么要type和key兩個參數呢?以前ASP.NET 1.x的同類函數只有key一個參數,這帶來的問題是可能兩個不同的控件設計時都使用了同一個key來注冊自己的腳本,結果其中一個控件腳本的成功輸出必然會抑制另一個控件腳本的輸出。加上了type參數,各控件都用自己的類型作為標識,這樣就能有效避免注冊時沖突。

為何無法真正避免沖突
關于這個問題,我們先看看ASP.NET內部定義的JavaScript是以什么方式命名的。通常,PRivate的全局函數或變量,命名都以雙下劃線開頭,例如大家熟悉的__doPostBack,或者是WebPartManager在客戶端使用的__wpm。而public或protected的全局函數或變量,一般就好像C#那樣使用Pascal命名法。具體的例子,大家可以用Reflector看看System.Web.UI的資源中的那些js文件。

我們暫時就假設這種命名法是正確的,然后模仿著去在自己開發的控件中實踐。事實上很多控件開發者也確實這樣做了,比較多的專業控件中你都能看到雙下劃線開頭命名的函數或變量,這至少可以避免和控件使用者在頁面上注冊的函數或變量沖突,因為在頁面上注冊的函數或變量通常都采用比較簡單的命名法。

假如現在我們要做一個浮動上下文菜單,也就是當你的鼠標移動到某個HTML元素上時該浮動菜單自動出現,當鼠標離開元素并且也不在菜單上時,菜單自動消失。為了方便用戶操作,我們允許用戶鼠標移動過程中稍微離開菜單區域,所以定義當鼠標離開菜單區域若干時間后才讓菜單消失,而這個時間在客戶端保存在__disappearAfter變量中。這個控件看起來什么問題都沒有,直到你把它和ASP.NET 2.0自帶的Menu控件放在同一個頁面上,因為Menu控件也有類似的功能,而且和我們的控件一樣Menu控件選擇了將時間變量保存在一個名為__disappearAfter的變量中。

現然,作為ASP.NET框架的使用者,框架沒有聲明這個變量的名字不允許使用,我用了有問題當然就可以認為是框架的錯。Brad Abrams寫了一本《.NET設計規范/Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries》,里面卻完全沒有提及JavaScript和CSS的規范,好像在ASP.NET中使用到的JavaScript與CSS都是瑣碎的不能在瑣碎的事情,所以完全不值得一提。

事實上,既然ASP.NET允許一個頁面上不同的控件設計者引入不同的JavaScript和CSS,就必須提供一種方法去管理潛在的命名沖突。如果是JavaScript,我們可以考慮使用ASP.NET Ajax的namespace來避免沖突,下一代代號為Orcas的Visual Studio和ASP.NET將內置ASP.NET AJAX支持,所以其內置控件所使用的JavaScript應該也會有namespace,這樣就有有效降低沖突概率。至于CSS命名沖突,暫時沒有好的解決放案,只能依賴控件設計者的習慣了,你可以考慮為你的控件根元素附上一個namespace以示區分,這樣也算是降低沖突概率的一個辦法。
http://m.survivalescaperooms.com/cathsfz/archive/2007/01/28/632288.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 湖州市| 荣昌县| 平果县| 靖宇县| 崇义县| 屯昌县| 乡宁县| 麟游县| 正宁县| 郧西县| 郓城县| 淮北市| 桦南县| 万盛区| 永靖县| 都江堰市| 马关县| 资溪县| 龙里县| 扎鲁特旗| 哈密市| 景洪市| 新沂市| 绵竹市| 沾化县| 阜宁县| 芦溪县| 大城县| 连平县| 平谷区| 黄冈市| 布尔津县| 罗定市| 海淀区| 漳浦县| 涟源市| 兴城市| 内乡县| 安新县| 元氏县| 藁城市|