2014-02-07 52 views
4

rx指導方針表示儘可能避免副作用,如果它們不可避免,則將它們放入do()(doAction in js)子句中。在rx中創建資源的副作用(反應式擴展)

但是,在用戶界面中的一個非常常見的副作用是創建一些資源(例如<div>),該資源被下游引用(通過子部件)。您必須捕獲這些資源的句柄,以便它們可以傳遞。例如。如果你有一組數據,每一個都需要一個div,你可以爲每個div創建一個div,並將這些div的句柄傳遞給子節點。

但doAction()會放棄副作用的返回值,因此您無法捕獲創建的對象的句柄。你必須在select()中做副作用。

我看着這一切都錯了嗎?創建的資源是狀態,並且是副作用的。你想要在流中的狀態,但是你不能把它放在流中,而不會在select()中加入副作用,這是禁忌的。

回答

4

請記住,它們只是指導方針。如果你想在你選擇功能的副作用,你知道它將如何使用然後去做。

但也......你有沒有考慮過創建分離的元素,只將它們附加到你的訂閱回調中的文檔?換句話說,這不是創造副作用的資源。只有當你對資源做些什麼的時候。我已經使用了這種模式幾次...

$(someElement).onAsObservable("click") 
    .select(function(ev) { 
      return $("<div>"); 
    }) 
    ...do stuff to detached div 
    .subscribe(function($el) { 
      // finally attach it 
      $(container).append($el); 
    }); 
+0

要允許將它傳遞給子窗口小部件,我需要捕獲中間流(在訂閱​​之前)。在這種情況下執行順序是否明確?我的意思是,孩子知道該元素是否插入到DOM中? divs =/* divs流* /; dispatch_to_children(divs); divs.subscribe(/ *插入DOM * /); 他們是否按順序執行?似乎依賴訂單可能不好,除非它在rx中有明確的定義。 – user1009908

+0

是Observable.using()與此問題有關?我在搜索「資源」時發現它。我不認爲introtorx涵蓋了這一點。不知道在哪裏找到例子。 – user1009908

+0

你可以發佈代表你的用例的代碼嗎?子元素在元素流中做什麼?有太多的變化,很難在沒有更多信息的情況下提供正確的建議。 – Brandon

2

這是FRP的一個常見問題。我還沒有找到比稍微改變規則更好的辦法。但是我沒有使用select/map,而是傾向於使用selectMany/flatMap,這使我可以直接返回一系列事件。

像下面一樣。 (該片段是Bacon.js代碼,但可以很容易地轉化爲RxJs)

var allClicks = event.flatMap(function(value) { 
    var widget = $("<input>") // etc 
    $("form").append(widget) 
    return widget.asEventStream("click") 
}) 

所以,對於每一個輸入事件,則創建一個新的片UI的,並從該一個返回事件流。結果流「allClicks」從生成的流中獲取所有事件。

相關問題