在上一篇文章講到SFData的設計的時候,已經簡單的提到了資料群組件要實現的功能,實際上,資料群組件,是SFData的一個外掛程式,這個外掛程式可以調用 SFData的所有的方法和事件,用來完成一些附加的功能和資料邏輯,例如,我們現在已經使用資料群組件功能實現了以下邏輯:
1.SFDataCalculateTimeComponent,在任務的起止時間發生變化的時候,檢查父任務的起止時間,保證每個概要任務的起止時間和其所有子任務的起止時間範圍一致; 2.SFDataOutlineComponent,完整的實現任務的大綱階層(OutlineLevel和OutlineNumber)的功能,在任務添加、移動、刪除的時候,所有的任務的大綱階層都跟隨變化 3.SFDataIdComponent完整的實現任務的ID的功能,在任務添加、移動、刪除的時候,保持ID始終作為任務的順序號 4.SFDataLogging,實現資料的更新日誌,將資料的更改統一都記錄下來,以便統一發送到資料庫儲存。
實際上,這隻是資料群組件的一些簡單的應用而已,依託SFData提供的強大功能,實際上可以完美的實現很多自訂的功能,例如資料的向上匯總,某些屬性的自動化佈建等等。 在資料群組件機制產生之前,我們曾經通過taskpropertyread實現過一個功能:某個任務不是大綱,而且任務的時間在10天以上的時候,則使用 特別的樣式來標識出來(標紅),以前雖然實現了這個功能,但是有明顯的問題:假如一個任務開始只有9天,後來被更改為11天,這個時候,這個任務實際上已 經應該被標紅了,可是時間的更改沒有引起列表顯示的重新整理(列表根本不知道還需要重新整理顯示),因此會出現問題。 假如通過資料群組件來實現,我們就可以在taskregister事件發生的時候根據任務的屬性來設定任務的樣式,然後在aftertaskupdate的時候根據新的任務屬性來重設任務的樣式,這樣就可以比較完備的實現需要的功能。 在提供這個例子之前,我們看看資料群組件需要實現哪些介面(因為資料群組件初始化的時候可以得到SFData對象,因此SFData和相關的實體類的屬性和方法都可以使用):
| 方法名稱 |
傳回值 |
說明 |
| initialize(data) |
null |
初始化此資料群組件 |
| remove() |
null |
停用此資料群組件 |
| depose() |
null |
銷毀此資料群組件 |
可以看到,這個需要實現的介面非常簡單(尤其是在看了資料配接器的一長列介面列表之後),其實最重要的是在initialize方法之中對data對象進行處理,捕獲一些事件以便達到控制資料的目的。 我們下面看一個實現資料配接器的範例,該範例實現以上說明的功能。
function MyAutoClassNameComponent(timeSpan){this.timeSpan=timeSpan?timeSpan:10*24*60*60*1000}MyAutoClassNameComponent.prototype=new SFDataComponent();//在這裡繼承SFDataComponentMyAutoClassNameComponent.prototype.initialize=function(data){ //綁定事件this.listeners=[SFEvent.bind(data,"taskregister",this,this.onTaskRegister),SFEvent.bind(data,"aftertaskupdate",this,this.onTaskUpdate),];}MyAutoClassNameComponent.prototype.setClassName=function(task){//這個函數設定任務的ClassName屬性,只有符合條件,才設定為TaskImportant,否則留空(置為預設)var name="";if(!task.getProperty("Summary") && task.getProperty("Finish").valueOf()-task.getProperty("Start").valueOf()>this.timeSpan){name="TaskImportant";}task.setProperty("ClassName",name);}MyAutoClassNameComponent.prototype.onTaskRegister=function(task){ //在任務初始化的時候設定值this.setClassName(task);}MyAutoClassNameComponent.prototype.onTaskUpdate=function(task,name,value,beforeValue){ //在有關聯的三個屬性變化的時候重新設定值if(name=="Summary" || name=="Finish" || name=="Start"){this.setClassName(task);}}MyAutoClassNameComponent.prototype.remove=function(){var listenr;while(listenr=this.listener.pop()){SFEvent.removeListener(this.listener)}} 雖然需要實現的介面並不是很多,但是實現一個資料群組件似乎並不容易,因為你必須非常瞭解你需要操作的屬性,並且對SFData的機制也有有一定的瞭解才行,不過你一旦瞭解之後,就可以實現很多複雜的邏輯了,而且,向日葵甘特圖也就能夠完美的與應用結合在一起了。