Sys.UI.DataView
為瞭解決展示資料的問題,我們需要用到一個全新的用戶端控制項,那就是Sys.UI.DataView了,簡稱DataView。我們會用DataView替換掉上一篇文章中所說到的人手拼接HTML的部分,用於迭代產生一個ul中的li元素,因此看起來是把DataView當作Repeater來用。實際上,DataView的功能類似於ListView加上DetailsView。
如果你把一個Array綁定到DataView上,它會顯示為一個ListView。與ListView的LayoutTemplate相類似的是,它也能夠定義控制項展示的整體布局,並且僅僅是迭代輸出其中的一小部分。例如說,編寫一個有thead的table,並且僅僅是迭代輸出thead之後的tr。在這方面,是DataView和ListView完全一致的。唯一不同的是,用戶端暫時還沒有DataPager這樣的控制項,所以DataView必須一次性的完整顯示整個Array的資料。
如果你把單個Object綁定到DataView上,它就會顯示為一個DetailsView。這使得你可以使用兩個DetailsView就做出經典的Master-Details展示模式,和在伺服器端分別用ListView和DetailsView做出來的一樣。當然,你不能指望DataView能夠好像DetailsView那樣,自動幫你分析每一個資料項目並映射出對應的HTML模板,因此HTML模板還是要你自己手寫的,但至少那是在HTML中編寫模板,編寫時能夠享受IDE帶來的各種好處,維護時也更容易看懂自己(或別人)原來寫下的HTML。
JavaScript文法
接下來,我們就要把DataView投入到實際應用中去了。首先,我們說一下如何用JavaScript來執行個體化一個DataView。有編寫ASP.NET AJAX用戶端代碼經驗的人對$create應該不會覺得陌生,因為DataView繼承自Sys.UI.Control,我們仍然可以用$create來執行個體化它。不過,在此之前,我們先要把對應的HTML編寫好:
以下為引用的內容: <ul id="itemTemplate" class="sysTemplate"> <li> <span class="award">{{ Award }}</span> <span class="winner">{{ Winner }}</span> <span class="film">{{ Film }}</span> </li> </ul> |
然後我們就可以基於itemTemplate這個HTML元素建立控制項了:
以下為引用的內容: $create(Sys.UI.DataView, { dataSource: new Sys.Data.AdoDataSource(), serviceUri: "WebDataService.svc", query: "OscarWinners" }, {}, {}, $get("itemTemplate")); |
現在,頁面顯示出來的結果和之前我們人手拼接HTML的版本完全一致,不過我們已經不在需要維護嵌入在JavaScript中的HTML代碼了。
聲明性文法
如果你覺得上面的做法還不夠好,要在pageLoad()裡面寫一個$create,那麼聲明性文法可能正是你需要的。大家應該記得很久很久之前,在ASP.NET AJAX還叫做Atlas的時候,就已經有過聲明性文法的設計,那就是xml-script。不知為何,後來Microsoft放棄了這一設計,現在聲明性文法又回來了,而且設計得比以前的xml-script還要更好。假如不用$create的話,通過聲明性文法執行個體化一個DataView僅需要這樣做:
以下為引用的內容: <body xmlns:sys="javascript:Sys" xmlns:dataView="javascript:Sys.UI.DataView" sys:activate="*"> <ul id="itemTemplate" class="sysTemplate" sys:attach="dataView" dataView:datasource="{{ new Sys.Data.AdoNetDataSource() }}" dataView:serviceuri="WebDataService.svc" dataView:query="OscarWinners"> <li> <span class="award">{{ Award }}</span> <span class="winner">{{ Winner }}</span> <span class="film">{{ Film }}</span> </li> </ul> </body> |
我們所需要更改的程式碼封裝括:在body元素上聲明有關的xmlns,將JavaScript中的名字空間映射到HTML上,或者你可以理解為映射到XML/XHTML上。
通過sys:activate="*"這個聲明,讓ASP.NET AJAX知道它需要去解釋頁面上所有的聲明性文法,並啟用對應的組件.將原本使用$create初始化時傳遞給執行個體的屬性、事件、引用改為用聲明性文法,直接寫在HTML元素的定義上.經過這三步,我們就可以將原來使用$create建立的組件改為使用聲明性文法建立了。
小結
DataView使得我們能夠使用HTML模板,來避免手工拼接HTML帶來的種種問題,同時聲明性文法讓我們能夠如同聲明伺服器端控制項一樣聲明用戶端組件。雖然在ASP.NET AJAX 4.0 Preview 3中這些功能仍有小bug,例如我想用聲明性文法建立我自己編寫的InPlaceEditoBehavior,這在初始化階段毫無問題,但卻會在頁面卸載銷毀對象之時拋出指令碼錯誤。
由於我覺得ASP.NET AJAX 4.0 Preview 4很快就要出來了,所以我也就不準備去深入研究Preview 3了,等Preview 4出來了再去好好看看原始碼。