RecordSet 使用小技巧
RecordSet是使用flash做RIA 時非常重要的東西,大筆的資料通常都是放在裏,然後不論新、刪、修、查(所謂的CRUD四大天王)都是先在裏面做完,然後透過某種binding機制反應到UI元件上。
之前的兩篇文章:
裏面曾經提過當時做案子遇到的困擾,主要是在於recordset雖然有一個固定不變的unique欄位 __ID__ 可做為辨識每筆資料用,但它並沒有提供一個類似 removeItemByID(id:Number) 這樣的指令來刪除資料,因此當時寫了一個 findByValue() 去依照 __ID__找出對應的 index,再用 removeItemAt()刪除。
經過半年後最近因為另一個案子又要回來惡搞 recordset,只是這次要做的東西比較複雜,因此有些過去的 dirty trick就要認真思考一下是否可以最佳化或改寫的更好用。
在開始之前,先稍微解釋一下 __ID__的運作原理,假設你有一個從db撈回來的resultset如下:
-
var _data:RecordSet;
-
_data = new RecordSet(["id", "parent", "title", "content"]);
-
//
-
_data.addItem({id:"1", parent:"", title:"1-this is label", content:"iiiiiiiiiiiiiiiiiiii"});
-
_data.addItem({id:"2", parent:"", title:"2-this is label", content:"iiiiiiiiiiiiiiiiiiii"});
然後將它的內容 dump出來
-
{_items: [{__ID__: 0, content: "iiiiiiiiiiiiiiiiiiii", id: "1", parent: "", title: "1-this is label"},
-
{__ID__: 1, content: "iiiiiiiiiiiiiiiiiiii", id: "2", parent: "", title: "2-this is label"},mTitles: ["id", "parent", "title", "content"],
-
uniqueID: 2}
這時可以發現 recordset已經自動為每筆資料加上一個新欄位,名稱就是 __ID__,更重要的是最後那個 uniqueID:2,這代表recordset內部會維護這個流水號,2即是下一筆插入資料的__ID__。
ok,那有了 __ID__後,可以怎麼用呢?recordset也提供了一個function叫做 getItemID(idx:Number),只要先用 recordset.selectedIndex 找到目前選取的項目,再將這個index number丟給 getItemID(idx:Number)就可以知道該item的unique ID是多少。
但真正重要的地方在於,知道 __ID__後該如何刪除?如前面所講,recordset沒有依照ID刪除資料的method,因此當年寫了一個小程式去達成。但今天仔細想了一下,其實 getItemID()就可以做到這件事。
-
for(var i=0;i<rs.length;i++){
-
if(rs.getItemID(i) == mark){
-
rs.removeItemAt(i);
-
break;
-
}
-
}
其中mark就是先前找出來要刪除item的index,這樣就可以輕鬆依id刪除資料了。
不過依照「凡走過必留下痕跡」原理,當初寫的那支 findByValue()其實也沒白廢,因為它可以自訂要搜尋的欄位(field),而不像 getItemID() 只能檢索 __ID__這一欄,因此理論上任何二維或多維的陣例結構也都可以用那支程式去找到特定欄位的資料,只是實作上可能要用 binary search 改寫一下才會更快。
另外附帶一提,Recordset在flash裏面的重要性實在是無可取代,尤其要非常熟悉整個 RecordSet - DataProvider - V2 component的運作原理,例如裏面的 modelChanged event 模式,這樣在開發application 時才能真正事半功倍;至於 DataBiding, DataSet等元件其實只是把基礎的東西包裝起來方便入門者使用,通常我都敬而遠之,因為包裝的越精美往往就代表彈性越小。
比較可惜的是原本想好好用一下 DeltaPacket與 SQLupdate之類的功能,無奈這玩意要運作就是得靠 Connector - DataSet - DataBinding - UI,這樣一來我寧願用 RecordSet 自已 implement一個類似的 deltaPacket功能啊~


Trackback this post | Subscribe to the comments via RSS Feed