rx指南说尽可能避免副作用,如果不可避免的话,将它们放在do()(js中的doAction)子句中。
然而,UI中非常常见的副作用是创建一些在下游引用的资源(例如< div>)(通过子窗口小部件)。您必须捕获这些资源的句柄,以便可以传递它们。例如。如果你有一个数组,每个都需要一个div,你可以为每个创建一个div,并将这些div的句柄传递给子节点。
但是doAction()会丢弃副作用的返回值,因此您无法捕获创建的对象的句柄。你必须在select()中做副作用。
我看这一切都错了吗?创建的资源是状态,并且是副作用。你想要流中的状态,但你不能把它放在流中而不将副作用放在select()中,这是禁忌的。
答案 0 :(得分:4)
请记住,它们只是指导方针。如果你想要一个副作用选择功能,你就会明白它将如何使用,那就去吧。
但是......你是否考虑过创建分离元素并仅将它们附加到订阅回调中的文档中?换句话说,不是资源的创造是副作用。只有当您对资源执行某些操作时。我已经使用过这种模式了几次......
$(someElement).onAsObservable("click")
.select(function(ev) {
return $("<div>");
})
...do stuff to detached div
.subscribe(function($el) {
// finally attach it
$(container).append($el);
});
答案 1 :(得分: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”从生成的流中获取所有事件。