上回我提了一個解決套用MasterPage時ClientID會突變的方法,其中提到: 我不喜歡document.getElementById('<% =TextBox1.ClientID%>').value這種ASP時代義大利麵式的寫法。

網友eric問: 為什麼不愛?

義大利麵先生,你是個好人,但是...

第一個理由是我喜歡Server-Side Logic編譯過並藏在DLL中,不要顯露在易被取得的ASPX內。不過,在這個應用情境上我們只用來標示WebControl.ClientID,稱不上是後端邏輯,原則上這點可以忽略。

第二個理由是我不喜歡在網頁裡夾帶<% ... %>這種ASP/ASPX專屬語法。在開發網站時,我常會先做一個配色噁心、版面混沌,只有程式設計師搞得出來,也只有程式設計師可以忍受的醜小鴨網頁,再交給團隊中的美學達人(我不喜歡稱這群專家叫美工,對一個配色殘障來說,她們是神~~~)用巧手變成天鵝。當網頁中摻雜了這些ASPX獨有語法,就容易因其他廠牌設計工具無法識別而在處理過程中受損。

第三個理由跟效能有點關係。所有的ASPX的內容,最後都會變成一個.cs檔,其中Client-Side Script、純HTML Tag等,都會被轉成字串處理,每用一次<% ... %>,就會切割出兩段字串。有點抽象是吧? 我用以下的例子說明:

<body>
    <form id="form1" runat="server">
    <div>
    </div>
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
&nbsp;<asp:Button ID="Button1" runat="server" Text="Button" />
    <br />
    <script type="text/javascript">
    alert('<% =TextBox1.Text %>');
    alert("<% =Button1.Text %>");
    </script>
    </form>
</body>

以上的寫法,實際上會被轉成以下的C# Code:

private void __Renderform1(HtmlTextWriter __w, Control parameterContainer)
{
    __w.Write("\r\n    <div>\r\n    \r\n    </div>\r\n    ");
    parameterContainer.Controls[0].RenderControl(__w);
    __w.Write("\r\n&nbsp;");
    parameterContainer.Controls[1].RenderControl(__w);
    __w.Write("\r\n    <br />\r\n    
<script type=\"text/javascript\">\r\n alert('"
);
    __w.Write(base.TextBox1.Text);
    __w.Write("');\r\n    alert(\"");
    __w.Write(base.Button1.Text);
    __w.Write("\");\r\n    </script>\r\n    ");
}

其中parameterContainer.Controls[0]就是TextBox1、parameterContainer.Controls[1]就是Button1。我們看到_Renderform1先吐出<div></div>,接著請TextBox1產生對應的HTML Tag,然後是&nbsp;,再來輪Button1產生對應的HTML Tag。接下來有意思了,如果我們這裡只是單純的Javascript Block,理論上應該一個__w.Write就會把整個Script Block輸出完。但因為我們用了<% =TextBox1.Text %>與<% =Button1.Text %>,所以整個Script Block被拆成五段輸出。分五次呼叫__w.Write,即使差異有限,但肯定會比一次呼叫來得沒效率,如果可以避免,我還是會設法閃過。

以上是我不愛義大利麵式寫法的理由,原則上這種寫法並非萬惡不赦,只是與我慣用的開發方式與哲學有點違背,算是個人偏好下的結論,這裡就細說從頭,給大家參考參考囉!


Comments

# by sam

針對MasterPage我遇到一個問題,無論我是在MasterPage or ContentPage裡面加一段javascript: <script type="text/javascript"> form1.htmlcontrolid.value = ""; </script> 最後出現的錯誤都是跟我說: 'form1'未被定義....... 這怎麼辦

# by Jeffrey

在Master Page中,前端產出HTML的Form名稱會變成aspnetForm,看你要將form1改成aspnetForm或是改用document.forms[0]。 http://forums.microsoft.com/MSDN-CHT/ShowPost.aspx?PostID=492906&SiteID=14&pageid=0#492906

# by alex

請教黑大: 以上的 private void __Renderform1(HtmlTextWriter __w, Control parameterContainer) 你是怎麼測出來的?往往想更深處探索,總是不得其門而入。

# by Jeffrey

to alex, 我慣用的做法是故意在ASPX中加入一個<% XXX %>讓程式產生編譯錯誤,預設的錯誤訊息畫面會有個"Show Complete Compilation Source"連結,點下去就可以看到讓你深入探索的東西囉!

Post a comment