HTML中的資料繫結(Data Binding)
先看看這樣兩個例子:
http://msdn.microsoft.com/workshop/samples/author/databind/dbevts.htm
http://msdn.microsoft.com/workshop/samples/author/databind/dbupdate.htm
不得不又一次佩服微軟。
這個是DataBinding的架構:
當然實現資料繫結有下面幾步:
第一步,定義資料來源
從IE4.0起,就支援下面四種資料來源:
Tabular Data Control (TDC)
TDC提供了一個簡單的訪問帶有格式的文字資料的方法,一般是csv檔案。
下面是一個簡單的示例:
<OBJECT CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83" ID=dsoComposer WIDTH=0 HEIGHT=0> <PARAM NAME="DataURL" VALUE="composer.csv"> </OBJECT>
Remote Data Service (RDS)
遠端資料服務,直接訪問遠端伺服器端的資料,Internet Explorer 4.0. RDS 通過OLE-DB 或 Open Database Connectivity (ODBC)來實現。
示例:
<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID=dsoComposer HEIGHT=0 WIDTH=0> <PARAM NAME="Server" VALUE="http://musicserver"> <PARAM NAME="Connect" VALUE="dsn=music;uid=guest;pwd="> <PARAM NAME="SQL" VALUE="select compsr_name from composer"> </OBJECT>
不過感覺有點安全性的問題,因為客戶端能看到這段程式碼。
XML Data Source
XML就不多說了,在IE4.0中這樣使用:
<APPLET
CODE="com.ms.xml.dso.XMLDSO.class"
ID="xmldso"
WIDTH="0"
HEIGHT="0"
MAYSCRIPT="true">
<PARAM NAME="URL" VALUE="composer.xml">
</APPLET>
Internet Explorer 5以上可以這樣:
<!--[if gte IE 5]>
<XML ID="xml1">
<topic-info>
<page-type>reference</page-type>
<member-type>property</member-type>
<persistent-name>ACCESSKEY</persistent-name>
<runtime-name readable="1" writeable="1">accessKey</runtime-name>
<abstract>Sets or retrieves the accelerator key for the object.</abstract>
</topic-info>
</XML>
<![endif]-->
另外IE還提供了一個XML資料島的概念:XML Data Islands.
MSHTML Data Source
html資料頁示例:
<H1 ID=COMPSR_FIRST>Hector</H1>
<MARQUEE ID=COMPSR_LAST>Berlioz</MARQUEE>
<DIV ID=COMPSR_BIRTH>1803</DIV>
<H2 ID=COMPSR_FIRST>Modest</H2>
<H3 ID=COMPSR_LAST>Moussorgsky</H3>
<BUTTON ID=COMPSR_BIRTH>1839</BUTTON>
<TEXTAREA ID=COMPSR_FIRST>Franz</TEXTAREA>
<XMP ID=COMPSR_LAST>Liszt</XMP>
<SPAN ID=COMPSR_BIRTH>1811</SPAN>
一旦定義可以這樣訪問:
<OBJECT ID=htmlComposer DATA="compdata.htm" HEIGHT=0 WIDTH=0> </OBJECT>
.第二步:繫結資料到HTML元素上
一般都是通過tag中的datasrc和datafld實現繫結的。例如:
<INPUT TYPE=TEXTBOX DATASRC="#dsoComposers" DATAFLD="compsr_last">
和
<TABLE DATASRC=#dsoComposer>
<TR>
<TD><DIV DATAFLD=compsr_first></DIV></TD>
</TR>
</TABLE>
這個是繫結表格的示例:
http://msdn.microsoft.com/workshop/samples/author/databind/dbtable.htm
其中資料來源:
<OBJECT id="tdcComposers" CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83">
<PARAM NAME="DataURL" VALUE="http://msdn.microsoft.com/workshop/samples/author/databind/composer.csv">
<PARAM NAME="UseHeader" VALUE="True">
<PARAM NAME="TextQualifier" VALUE="'">
</OBJECT>
繫結的table
<TABLE datasrc=#tdcComposers>
<THEAD><TR STYLE="font-weight:bold">
<TD>First</TD><TD>Last</TD><TD>Birth</TD><TD>Death</TD><TD>Origin</TD>
</TR></THEAD>
<TBODY>
<TR>
<TD><DIV datafld="compsr_first"></DIV></TD>
<TD><DIV datafld="compsr_last"></DIV></TD>
<TD><DIV datafld="compsr_birth"></DIV></TD>
<TD><DIV datafld="compsr_death"></DIV></TD>
<TD><DIV datafld="origin"></DIV></TD>
</TR>
</TBODY>
</TABLE>
這就是效果了:
First | Last | Birth | Death | Origin |
Hector | Berlioz | 1803 | 1869 | France |
Modest | Moussorgsky | 1839 | 1881 | Russia |
Franz | Liszt | 1811 | 1886 | France |
Antonio | Vivaldi | 1678 | 1741 | Italy |
Johann Sebastian | Bach | 1685 | 1750 | Germany |
Ludwig van | Beethoven | 1770 | 1827 | Germany |
Wolfgang Amadeus | Mozart | 1756 | 1791 | Austria |
Joseph | Haydn | 1732 | 1809 | Germany |
Claude | Debussy | 1862 | 1918 | France |
第三步:資料的動態新增,刪除等等(物件模型)
當然繫結可以是動態的:
在script中:
span1.dataSrc = "#dsoComposer";
span1.dataFld = "compsr_first";
html是這樣的:
<SPAN DATASRC="#dsoComposer" DATAFLD="compsr_first"></SPAN>
而且可以訪問資料來源的ado:
var oRecordSet = dsoComposer.recordset;
自然就有oRecordSet .MoveNext等等。
如:
<INPUT ID=cmdNavFirst TYPE=BUTTON VALUE="<<"
onclick="tdcComposers.recordset.MoveFirst()">
<INPUT ID=cmdNavPrev TYPE=BUTTON VALUE=" < "
onclick="tdcComposers.recordset.MovePrevious();
if (tdcComposers.recordset.BOF)
tdcComposers.recordset.MoveFirst();">
<INPUT ID=cmdNavNext TYPE=BUTTON VALUE=" > "
onclick="tdcComposers.recordset.MoveNext();
if (tdcComposers.recordset.EOF)
tdcComposers.recordset.MoveLast();">
<INPUT ID=cmdNavLast TYPE=BUTTON VALUE=">>"
onclick="tdcComposers.recordset.MoveLast()">
還可以這樣用:
<SCRIPT Language="VBScript">
For Each objFld in rsAttendees.Fields
document.write("The field name is " & objFld.Name & "<BR>")
document.write("The field value is " & objFld.Value & "<BR>")
Next
</SCRIPT>
新增刪除記錄就是:oRecordSet.AddNew()以及oRecordSet.Delete()。
第三步:響應各種資料事件(事件模型)
如何在資料更改後做出相應的處理?
msdn中提供的方法是這樣的:
<SCRIPT FOR=cboSort(資料來源名) EVENT=onchange(事件名)>
……
</SCRIPT>
這些是事件名列表:
Event | Bubbles | Cancelable | Applies to | Introduced In Internet Explorer Version |
---|---|---|---|---|
onbeforeupdate | True | True | bound elements | 4.0 |
onafterupdate | True | False | bound elements | 4.0 |
onrowenter | True | False | DSO | 4.0 |
onrowexit | True | True | DSO | 4.0 |
onbeforeunload | False | False | window | 4.0 |
ondataavailable | True | False | DSO | 4.0 |
ondatasetcomplete | True | False | DSO | 4.0 |
ondatasetchanged | True | False | DSO | 4.0 |
onerrorupdate | True | True | bound elements | 4.0 |
onreadystatechange | True | False | DSO | 4.0 |
oncellchange | True | False | DSO | 5.0 |
onrowsinserted | True | False | DSO | 5.0 |
onrowsdelete | True | False | DSO | 5.0 |
怎麼樣?
我覺得http://msdn.microsoft.com/workshop/samples/author/databind/dbevts.htm算是一個應用比較綜合的例子了,好好研究一下,必有收穫。
網上有不少利用資料繫結實現分頁的示例,其實資料繫結還可以做更多的事情吧?應該在rich client裡面有非常大的應用,例如製作非常複雜的datagrid。
現在想進一步搞清楚的是如何簡便實現與伺服器端的同步,因為客戶端的資料繫結是對伺服器端沒有影響的(你可以從伺服器端生成資料來源,但是在客戶端的操作不會自動返回伺服器),msdn上說RDS可以,但是這種方法太笨拙了吧,又不安全。