4

rx 指南说尽可能避免副作用,如果它们不可避免,则将它们放在 do()(js 中的 doAction)子句中。

然而,在 UI 中一个非常常见的副作用是创建一些资源(比如 <div>)被下游引用(由子小部件)。您必须捕获这些资源的句柄,以便传递它们。例如,如果您有一个数据数组,每个数据都需要一个 div,您将为每个数据创建一个 div,并将这些 div 的句柄传递给子项。

但是 doAction() 会丢弃副作用的返回值,因此您无法捕获已创建对象的句柄。您必须在 select() 中执行副作用。

我看这一切都错了吗?创建的资源是状态,并且具有副作用。你想要流中的状态,但是你不能把它放在流中而不把副作用放在 select() 中,这是禁忌的。

4

2 回答 2

4

请记住,它们只是指导方针。如果您想在选择功能时产生副作用,并且您了解它的使用方式,那么就去做吧。

而且...您是否考虑过创建分离元素并仅在订阅回调中将它们附加到文档?换句话说,副作用不是资源的创建。只有当你对资源做某事时。这种模式我用过几次...

$(someElement).onAsObservable("click")
    .select(function(ev) {
            return $("<div>");
     })
     ...do stuff to detached div
     .subscribe(function($el) {
          // finally attach it
          $(container).append($el);
     });
于 2014-02-07T02:13:29.587 回答
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 并从该 UI 返回一个事件流。结果流“allClicks”从生成的流中获取所有事件。

于 2014-02-07T07:18:09.533 回答