實際上eval方法是templatecontrol的,而system.web.ui.page和system.web.ui.usercontrol都繼承于templatecontrol,所以我們可以在page和usercontrol上直接調(diào)用個方法。
page.eval方法可以幫助我們更好的撰寫數(shù)據(jù)綁定表達式,在asp.net 1.x時代,數(shù)據(jù)綁定表達式的一般形式是:
<%# databinder.eval( container , “dataitem.name”) %>
而在asp.net 2.0中,同樣的代碼,我們可以這樣寫:
<%# eval( “name” )%>
asp.net 2.0是怎么實現(xiàn)的呢?我們先從eval方法來研究,通過反射.net framework 2.0類庫的源代碼,我們可以看到這個方法是這樣實現(xiàn)的:
protected internal object eval(string expression)
{
this.checkpageexists();
return databinder.eval(this.page.getdataitem(), expression);
}
第一行我們不必管,這是檢查調(diào)用的時候有沒有page對象的,如果沒有則會拋出一個異常。
關(guān)鍵是第二行:
return databinder.eval(this.page.getdataitem(), expression);
page.getdataitem()也是2.0中新增的一個方法,用途是正是取代asp.net 1.x中的container.dataitem。
看來不摸清楚getdataitem()方法,我們也很難明白eval的原理。getdataitem的實現(xiàn)也很簡單:
public object getdataitem()
{
if ((this._databindingcontext == null) || (this._databindingcontext.count == 0))
{
throw new invalidoperationexception(sr.getstring("page_missingdatabindingcontext"));
}
return this._databindingcontext.peek();
}
我們注意到了有一個內(nèi)部對象_databindingcontext,通過查源代碼發(fā)現(xiàn)這是一個stack類型的東西。所以他有peek方法。而這一段代碼很容易看懂,先判斷這個stack是否被實例化,然后,判斷這個stack里面是不是有任何元素,如果stack沒有被實例化或者沒有元素則拋出一個異常。最后是將這個堆棧頂部的元素返回。
asp.net 2.0用了一個stack來保存所謂的dataitem,我們很快就查到了為這個堆棧壓元素和彈出元素的方法:control.databind方法:
protected virtual void databind(bool raiseondatabinding)
{
bool flag1 = false;//這個標(biāo)志的用處在上下文中很容易推出來,如果有dataitem壓棧,則在后面出棧。
if (this.isbindingcontainer)//判斷控件是不是數(shù)據(jù)綁定容器,實際上就是判斷控件類是不是實現(xiàn)了inamingcontainer
{
bool flag2;
object obj1 = databinder.getdataitem(this, out flag2);//這個方法是判斷控件是不是有dataitem屬性,并把它取出來。
if (flag2 && (this.page != null))//如果控件有dataitem
{
this.page.pushdatabindingcontext(obj1);//把dataitem壓棧,pushdatabindingcontext就是調(diào)用_databindingcontext的push方法
flag1 = true;
}
}
try
{
if (raiseondatabinding)//這里是判斷是不是觸發(fā)databinding事件的。
{
this.ondatabinding(eventargs.empty);
}
this.databindchildren();//對子控件進行數(shù)據(jù)綁定,如果這個控件有dataitem,則上面會將dataitem壓入棧頂,這樣,在子控件里面調(diào)用eval或者getdataitem方法,就會把剛剛壓進去的dataitem給取出來。
}
finally
{
if (flag1)//如果剛才有壓棧,則現(xiàn)在彈出來。
{
this.page.popdatabindingcontext();//popdatabindingcontext就是調(diào)用_databindingcontext的pop方法
}
}
}
至此,我們已經(jīng)可以完全了解asp.net 2.0中g(shù)etdataiten和eval方法運作的原理了,下一次我打算研究asp.net 2.0中的新的bind語法。
有提供bind語法資料的和提出好建議的酌情給分,up、頂?shù)确謺苌伲臃终邿o分。
新聞熱點
疑難解答
圖片精選