最近在做個包含了大量重覆樣式的控制項的網站. 如果用MVC的話,我可以針對每個需要單獨塊編輯的Model寫一個局部視圖. 然後根據不同邏輯需求拼起來.用現成MVC框架非常容易做到. 但環境是3.5的最高只能用MVC2,沒有razor語法,加上沒裝開發環境. 於是想乾脆自己寫一個模板生成HTML的框架,
最近在做個包含了大量重覆樣式的控制項的網站.
如果用MVC的話,我可以針對每個需要單獨塊編輯的Model寫一個局部視圖.
然後根據不同邏輯需求拼起來.用現成MVC框架非常容易做到.
但環境是3.5的最高只能用MVC2,沒有razor語法,加上沒裝開發環境.
於是想乾脆自己寫一個模板生成HTML的框架,一開始也報了點好玩的想法.
但做到後面就覺得,和MVC比起來功能太弱,但自由度很高,想什麼樣功能都不受限制.
主要代碼並不多.
我用json數據來保存視圖配置,反序列化得到實例,然後根據手動定義的視圖配置+事先定義好的Html模板代碼->生成最終html.
分成了幾種類型:
page:頁面
panel:面板
control:控制項.
偷懶沒有寫各種控制項類,所有屬性放這個類里,目前功能不多還好,如果擴展越多就比較亂了.
Html模板代碼類似這樣:用{屬性名}來替換數據.
<div class="item"><span class="iname"><i>{require}</i>{label}</span>
<input id="{name}" name="{name}" placeholder="{placeholder}" text="{label}"
onblur="" maxlength="{maxlength}" type="text"></div>
Json數據類似這樣:(後來寫了一個自動生成基礎json數據的工具,生成預設配置的json數據)
{ "label":"標題", "name":"Basic", "controls":[ { "name":"id_type", "label":"證件類型", "type":"combox", "column":"BusinessIDCardInfo", "valid":"checkNull" }, "panels":[ ] }
最後在aspx頁面調用組合各個page.支持多個頁面跳轉的功能.check2是由跳轉按鈕觸發,每個Page對象一個跳轉函數,該函數內,先執行框架內置驗證函數checkfunc(也是每個page一個),然後
可以執行自定義驗證函數.最後調用next2(),也是框架內置的跳轉函數,根據當前頁數決定是跳轉還是提交.
<asp:Content ID="Content1" ContentPlaceHolderID="content" Runat="Server"> <input type="hidden" name="pbtype" value="p" /> <%=WechatPrefill.Manager.GetHtml("pBasic",1,2,"新的標題") %> <%=WechatPrefill.Manager.GetHtml("pEbank",2,2) %> <script>
function check2() {
function check2() {
if (!checkfunc2()) return;
next2();
}
</script>
功能類其實很少,本人寫代碼習慣是寫少一點.
貼一下主要功能代碼:
根據反射obj的屬性,根據名字替換模板中指定文本.
這裡除了string,int還有Dictionary類型需要特別處理.
所有模板替換都在這一個函數里完成.
public static string GetHtml(string tempHtml,object obj) { var t = obj.GetType(); foreach (var field in t.GetFields()) { var value=field.GetValue(obj); if (value == null) { tempHtml = tempHtml.Replace("{" + field.Name + "}", ""); continue; } ..... }
這是Panel類,先替換標題文本,獲取panel的模板數據,反射替換模板.
public class Panel : Itemplate { public string name; public string label; public string img; public List<Control> controls; public string Html() { label = Manager.GetLabel(label); var temp = Template.GetTemplate("panel"); return Template.GetHtml(temp, this); } }
最後還有生成數據方面.
因為已經用了反射比較影響效率,本來不想用遞歸,不過由於屬性的層級可能很深(可能是A.b.C.D.E.property)所以,如果完全用迴圈,代碼要寫很長.
還是遞歸比較簡單.