2011-10-28 21 views
2

我想知道如何設計反應香蕉來處理以下情況:如何處理反應香蕉中的多個窗口和單個數據結構

假設我有一箇中央數據結構。用戶可以自由地打開和關閉顯示數據的任意數量的不同類型的窗口,並允許用戶對其進行修改。

因此,考慮到這一點的性質,我認爲只是試圖創建一個大的網絡將運作良好。這是每個窗口將有一個網絡,並以某種方式連接的東西嗎?

在這樣的其他情況下,我將數據結構放在每個人都發送更新的單個通道後面。然後數據結構會「發佈」窗口全部「收聽」的更新(火災事件)。

回答

3

我的項目中有一個相關的問題,它使用類似於MVC體系結構的東西。中央數據結構被標記爲

-- the data is a tree, and it's kept as a zipper to the current node 
Discrete MyDataZip 

這裏是我的控制器聲明的精簡版本:

data Controller st = Controller { 
    dState  :: Discrete st 
,eUpdateZip :: Event (MyDataZip -> MyDataZip) 
,eResponse :: Event (IO()) 
,bDiagChange :: Behavior (Diagram Cairo R2 -> Diagram Cairo R2) 
} 

當構建,大多數控制器得到dZip :: Discrete MyDataZip參考,但沒有辦法修改它直接。控制器指定更新的唯一方法是通過Controller數據結構中的eUpdateZip流。

將多個控制器組裝成一個圖形,該圖形只是放置在存在型包裝器data EControl = forall st. EControl (Controller st)中的控制器列表。我只是mconcat所有的個人eUpdateZip參數來獲得單一的Event (MyDataZip -> MyDataZip)流,這是用來創建Discrete MyDataZip。整個事情是有效的,因爲創建新控制器是純粹的,所以它可以在同一個let綁定中完成,從而允許遞歸引用。

打開新窗口和其他IO任務在eResponse流中完成,其類似mconcatd然後傳遞給reactimate

您可以查看darcs repo瞭解更多詳情,請查看「src/Jaek/UI/Controllers /」和「src/Jaek/UI/ControlGraph.hs」。

編輯:中心問題是,一個大型網絡從開發人員的POV相當笨拙。您可以通過細分網絡來降低複雜性,這是一個很好的解決方案。在我的設計中,我通過使被動參與者符合特定的控制器模型,併爲這些模型進行交互創建明確的方法,向網絡引入了很多結構。由於我的控制器是持久性的,所有這些都是靜態設置的,但它可以動態完成,在這種情況下,我可能會讓控制器管理器在一個線程中運行,並且生成新控制器(如打開新窗口)的操作會發送消息給線程來創建一個新的控制器。

1

目前,無法在事件網絡編輯完成後向事件網絡添加或刪除外部事件(例如反應式香蕉版本0.4.3)。換句話說,不可能在單個事件網絡中描述你的任務。不過,你可以利用外部事件或多個事件的網絡,從而導致類似下面的解決方案:

  • 地圖窗口的動態收集到一組靜態事件源(又名AddHandler的東西)的。
  • 或者每個窗口使用一個事件網絡,並通過外部事件源進行通信。
  • 或者每次添加或刪除新窗口時重新編譯單個事件網絡。不幸的是,內部狀態將會丟失,因此您必須將其明確並在外部捕獲(例如在IORef中)。 (這可能是最不滿意的解決方案。)
+1

這個故事在'reactive-banana' 0.8中是否一樣?現在我們已經有了「執行」和朋友,我想知道現在是否有可能以更清晰的方式做到這一點。 – ocharles

+2

@ocharles是的,現在可以通過動態事件切換。 「BarTab.hs」示例展示了類似的情況,但不是可變數量的窗口,而是可變數量的文本輸入框。 –

相關問題