Friday, December 05, 2008 - 文章

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寫法有三種:

  1. One-Way, One-Time:
    如同先前講過的{{ propName }}寫法,set_data時會將資料值寫入,之後就不再有任何互動。
  2. One-Way:
    要寫成{binding propName},set_data後,若當初提供資料來源的Javascript物件變動,該值亦會自動更新。 最主要應用於Master-Detail的情境。
  3. 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測試優先的做法,撰寫測試付出的額外成本十分可觀,時程不易壓縮且人力耗用大,嚇走了不少決策者與開發者。

大家面對這樣的情境時,會採取何種策略呢?

搜尋

Go

<December 2008>
SunMonTueWedThuFriSat
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
 
RSS
【工商服務】
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication