昨天发了一篇关于模板的功能介绍的文章,今天我想说说我为什么想设计一个自己的模板分析程序而不愿意使用微软老大给我们做好的近似完美的一切.
做网站的本质无非是一些html加一点点css,再放一些Js做调料,这加工出来的就是各种各样的网站平台;但微软老大却先把html和css做成美国大汉堡,再把JS弄成根香肠提供给广大的食客。虽然大家都喜欢这种大餐,但吃多也终究不是很好,而且有时候我们需要的是一份简单的农家小炒,所以我就通过几天的努力让自己重新有机会直接与HTML、CSS、JS等打交道。
前面有朋友说我只是把<asp:Repeater id="rptTables" > 换成了{repeater rptTables},虽然我当时不太同意这种说法,但细想一下其实这种说法也是对的。这所以要把<asp:Repeater id="rptTables" > 换成{repeater rptTables},是因为后者比前者更容易分析。也有朋友说我是用另一种方式重新实现了另一种ASP.NET控件,其实这也是正确的,ASP.NET控件的好处和使用方式已经是广大.NET程序员所熟悉的东东,为了使别人看到我的方案不至于不知所谓,我也只能实现和它差不多的方案,而且我知道我要的是直接与最原始的原素打交道的权力,而不是要去否定别的方案和形式。
说了这么多,应该开始说说我的代码了,以下是模板分析的主要代码片段,具体的分析我会在后续的文章中进行说明。
1
internal class Template : IUI.ITemplate
2
{
3
bool _isInstantiateIn = false;
4
private Dictionary<string, UIModel.Control> dicContainer;
5
private List<Control> listContainer;
6
private List<Token> tokens;
7
private char[] chrs;
8
9
public Template()
10
{
11
dicContainer = new Dictionary<string, Control>();
12
listContainer = new List<Control>();
13
tokens = new List<Token>();
14
}
15
16
public void InstantiateIn(ref string input)
17
{
18
_isInstantiateIn = true;
19
chrs = input.ToCharArray();
20
21
InitTokens(chrs);
22
23
GroupTokens();
24
25
InitTags();
26
}
27
28
public bool ContainsKey(string id)
29
{
30
return dicContainer.ContainsKey(id);
31
}
32
33
public Ctit.TTCCostPro.UIModel.Control FindControl(string id)
34
{
35
if (dicContainer.ContainsKey(id))
36
{
37
return dicContainer[id];
38
}
39
else
40
{
41
return null;
42
}
43
}
44
45
public string Render()
46
{
47
if (!_isInstantiateIn)
48
throw new Exception("Template must InstantiateIn before render!!");
49
50
//StringBuilder sb = new StringBuilder();
51
52
//for (int i = 0; i < tokens.Count; i++)
53
//{
54
// sb.AppendFormat("First: {0}, Second: {1}, StartIndex: {2}, EndIndex: {3} TokenType: {4} InnerStart: {5}, InnerEnd: {6} <br />", tokens[i].First, tokens[i].Second, tokens[i].StartIndex, tokens[i].EndIndex, tokens[i].TokenType.ToString(), tokens[i].InnerStart, tokens[i].InnerEnd);
55
//}
56
//return sb.ToString();
57
58
StringBuilder sb = new StringBuilder();
59
60
int k = 0;
61
62
for (int i = 0; i < listContainer.Count; i++)
63
{
64
while (k < listContainer[i].StartIndex && k < chrs.Length)
65
{
66
sb.Append(chrs[k]);
67
k++;
68
}
69
70
if (listContainer[i].Display)
71
{
72
StringBuilder sHtml = new StringBuilder();
73
RenderControl(listContainer[i], sHtml);
74
sb.Append(sHtml);
75
}
76
k = listContainer[i].EndIndex + 1;
77
}
78
79
while (k < chrs.Length)
80
{
81
sb.Append(chrs[k++]);
82
}
83
84
return sb.ToString();
85
}
86
87
private void RenderControl(Control ctr, StringBuilder sHtml)
88
{
89
switch (ctr.TagName.ToLower())
90
{
91
case "repeater":
92
{
93
Repeater rpt = (Repeater)ctr;
94
95
96
if (rpt.DataSource != null)
97
{
98
CreateInnerTemplate(sHtml, rpt, rpt.HeaderTemplate);
99
IEnumerable date = (IEnumerable)rpt.DataSource;
100
101
foreach (object o in date)
102
{
103
rpt.Current = new Dictionary<string, string>();
104
PropertyInfo[] properties = o.GetType().GetProperties();
105
foreach (PropertyInfo p in properties)
106
{
107
rpt.Current.Add(p.Name, p.GetValue(o, null).ToString());
108
}
109
CreateInnerTemplate(sHtml, rpt, rpt.ItemTemplate);
110
}
111
112
CreateInnerTemplate(sHtml, rpt, rpt.FooterTemplate);
113
}
114
115
break;
116
}
117
case "view":
118
{
119
break;
120
}
121
case "eval":
122
{
123
TextControl eval = (TextControl)ctr;
124
if (eval.ParentNode.Current.ContainsKey(eval.Second))
125
{
126
sHtml.Append(eval.ParentNode.Current[eval.Second]);
127
}
128
break;
129
}
130
default:
131
{
132
break;
133
}
134
}
135
}
136
137
private void CreateInnerTemplate(StringBuilder sHtml, Repeater rpt, InnerIndex inner)
138
{
139
if (Controls.HadChildTag(inner, rpt))
140
{
141
List<Control> ls = Controls.GetChildNodes(inner, rpt);
142
int k = inner.InnerStart;
143
144
for (int i = 0; i < ls.Count; i++)
145
{
146
while (k < ls[i].StartIndex && k < inner.InnerEnd)
147
{
148
sHtml.Append(chrs[k++]);
149
}
150
151
if (ls[i].Display == true)
152
{
153
RenderControl(ls[i], sHtml);
154
}
155
156
k = ls[i].EndIndex + 1;
157
}
158
159
while (k < inner.InnerEnd)
160
{
161
sHtml.Append(chrs[k++]);
162
}
163
}
164
else
165
{
166
CharsManager.Copy(chrs, inner, sHtml);
167
}
168
}
169
170
private void AddSingleTag(Control parentNode, Token token)
171
{
172
switch (token.First.ToLower())
173
{
174
case "page":
175
case "eval":
176
{
177
TextControl textInfo = new TextControl();
178
textInfo.StartIndex = token.StartIndex;
179
textInfo.EndIndex = token.EndIndex;
180
textInfo.First = token.First;
181
textInfo.Second = token.Second;
182
textInfo.ParentNode = parentNode;
183
textInfo.TagName = token.First;
184
185
//把根结点元素放在列表容器里面去.
186
if (parentNode == null)
187
{
188
listContainer.Add(textInfo);
189
}
190
else//子结点放在父结点下面
191
{
192
parentNode.AppendChild(textInfo);
193
}
194
break;
195
}
196
default:
197
break;
198
}
199
}
200
201
private void AddComplexTag(Control parentNode, ref int index)
202
{
203
if (index >= tokens.Count)
204
return;
205
206
Token token = tokens[index];
207
208
switch (token.First.ToLower())
209![]()