-
ASP.NET AJAX Templates - Data Binding與Master-Detail連動
-
【ASP.NET AJAX Templates系列】
先前的ASP.NET AJAX Templates介紹都集中在如何將資料反應到顯示元素上,記得嗎? 在Server Control Template中,我們可以寫Eval也可以寫Bind,當使用Bind時,更改Template裡的資料,會反應回原始的資料來源上,這在ASP.NET AJAX Client Templates也做得到!
進一步來說,ASP.NET AJAX Client Templates的Binding寫法有三種:
- One-Way, One-Time:
如同先前講過的{{ propName }}寫法,set_data時會將資料值寫入,之後就不再有任何互動。
- One-Way:
要寫成{binding propName},set_data後,若當初提供資料來源的Javascript物件變動,該值亦會自動更新。 最主要應用於Master-Detail的情境。
- Two-Way:
一樣是寫成{binding propName},但若同一屬性用在兩個HTML元素上,則更改其中一個,另一個也會跟著變化。
接下來,我們就將前述宣告式AJAX Templates的例子,做一些修改,改裝成Master-Detail形式,並透過Two-Way Binding加上酷炫的編輯功能。
首先,原本的Table維持不變,但要多加一個dataview:sys-key="dataViewObjName"的屬性,如此,便可利用這個變數名稱存取背後的Sys.UI.DataView物件。而這個物件,也將會是Detail View要Bind的對象。
我們建立一個<div>內包<fieldset>做為簡陋的Detail View展示:
<div
sys:attach="dataview"
dataview:data="{binding selectedData, source={{ master }}}" class="sys-template" style="font-size: 9pt; width:300px;"
>
<fieldset>
Person: {{Id}} {{Name}} <br /> Score=<input type="text" value="{binding Score}" /> </fieldset>
</div>
值得注意的是,Score分數的部分,我們用了<input>,value則寫成{binding Score} [Updated: 目前版本的解析邏輯不佳,大括號內名稱前後不要插入空白],如此,當數字內容修改,就會反映回來源物件的Score屬性。但原先Table中我們寫的是<td style="text-align: right;">{{Score.format("N2")}}</td>,這是One-Time式Binding,不會即時反應值的變化,因此得改成{binding Score}的格式,但這衍生另一個問題,原來我們對數字做了格式化,加上千位號以及限定小數兩位,binding表示法裡必須直指Score,而不能用Score.format("N2")。要解決這個問題,要造convert函數,其表示法為{binding propName, convert=convertFuncName}。在我們的範例裡,我們新增一個函數fmtNum:
<script type="text/javascript">
function fmtNum(value)
{ return parseFloat(value).format("N2"); } </script>
並改寫成<td style="text-align: right;">{binding Score, convert=fmtNum}</td>
如上圖所示,按了Id欄位,下方Detail View就會即時顯示所選取項目的內容,而修改Score後,修改後的分數會立即回饋到上方的Master View。
很酷吧!!
-
測試的哲學
-
最近手上的一個專案漸入高潮,各方人馬分頭進行的各模組也開始進入整合階段,引發一個有趣的議題。
系統被拆解成多個模組分工開發,但模組間有很密切的相關性。例如: 模組A寫入的資料,要變成模組B報表的來源;模組C修改的基本資料檔,會左右模組A寫入資料的邏輯,也影響模組B報表產出的結果。
為求開發速度,開發初期各模組團隊是各自獨立進行的,準備測試資料時,以各模組自己可以運作為目標。由於尚未跟其他相關模組整合(例如: 模組A寫入資料前,要先經過模組C驗證資料有效性,但模組C根本還沒寫好,所以就先寫一段假邏輯替代或索性跳過驗證),寫入資料庫的資料在完整性及合理性尚未達到系統最終要求。加上開發期間程式修修改改,程式錯誤時也塞入了一些邏輯不符的資料沒有清除。
可以想見,現階段資料庫裡的資料千奇百怪,模組B產生的報表自然一塌糊塗,明明依著系統規格書的邏輯寫,因資料不合理,就跑出讓人吐血的結果。最理想的狀況當然是要求所有資料得符合系統規範,不該是NULL的就不得留白,數字大小也必須落在合理範圍。但從實務面來說,這等同於將整合測試的部分工作提前,要求重整資料勢必要先中斷各模組開發人員的工作,停下來協調各模組以產生合理資料,這個停頓時間看來不會太短,將嚴重影響各組的既定時程規劃。
看來是一個兩難抉擇,所以變成了可以討論的話題。大家討論了一下,發現彼此看法不盡相同,形成了有趣的對照,也反映了不同的開發哲學。
有人贊成依原先計劃,待整合測試階段再驗證結果正確性。理由是這樣較不會破壞各組既有的時程規劃,搞亂大伙漸入佳境的工作節奏,系統的完成進度也較能符合預期。再者,及時有具體的成果(不論結果對錯)產出,對於"安定人心"也有很大的指標性意義。(不要小看這一點,有實戰經驗的人應該會同意"心理層面"因素對專案成敗的影響並不亞於時程、功能、效能等議題)
而我,或許是受了TDD(Test Driven Development)的荼毒,深信程式應該一開始就要做對(Do Right At First Time, DRAFT),錯誤愈遲發現、愈晚修正,代價將呈等比級數倍增。例如: 現在因為測試資料不正確,在寫第一支報表時無法檢視結果,未察覺某段邏輯不正確,那麼同樣的錯誤邏輯觀念就會被複製到第二支、第三支報表裡,待進入整合測試階段時才發現,就得回頭重新檢查修改所有的程式。
而從另一個角度來看,先略過正確性檢查的開發方式在時程上的表現雖較亮眼,時程到了"東西都有如期交出",但其正確性卻不被保證,也許整合測試後還要花上可觀的時間將程式結果修到正確。換句話說,"時程一如預期"可能只是假象,因為當初時程要求的一定是指某個時點應是交付"正確可用的程式",而非"看起來可以跑的程式"。當外界對程式品質失去信心,降低了對開發人員的信任度,對開發團隊而言,會是一項危機。話雖如此,老執著於測試正確性、開發進度停頓、大半天程式連影子都看不到的開發團隊,實在也高明不到哪裡去...
這番分析下來,兩種做法實在沒有明顯的優劣,頗像傳統測試哲學對決TDD的泰勢。TDD如果只有優點沒有缺點,早就變成大家奉行不渝的鐵律,事實上,TDD測試優先的做法,撰寫測試付出的額外成本十分可觀,時程不易壓縮且人力耗用大,嚇走了不少決策者與開發者。
大家面對這樣的情境時,會採取何種策略呢?