在 BaconJS 中使用 combineAsArray 改变流集

Use combineAsArray on Changing Set of Streams in BaconJS

已找到问题- how should I keep a running total of several values with bacon.js?

我已经找到上面的问题,它涉及一组静态属性。但是,我对一种变体感兴趣,其中属性集是动态的。

我的具体情况是我有一组具有可编辑成本的事物,形成一个可观察的 属性。从这些中,我将属性与 combineWith 结合起来以获得所有事件的总成本。 (代码在最后)

现在,我已经使用 jQuery 为一组静态事件正确连接了属性以获得正确的值,但我的想法是用户可以添加(或删除)一个事件任意,计算的总数将相应更新。

我有一个模糊的暗示,这项工作的工具是 combineAsArray 并且在我所有流的公共父级上巧妙地使用事件侦听,或者可能是某种 Bacon.Bus(动态地将流插入其中?),但我现在 真的 正在旋转我的轮子...

(伪)代码

<table>
  <tr>
    <td><input id="thing1" value="40"></input></td>
  </tr>
  <tr>
    <td><input id="thing2" value="40"></input></td>
  </tr>
</table>


$(function() {
  stream1 = $("#input1").asEventStream("change blur keyup").toProperty();
  stream2 = $("#input2").asEventStream("change blur keyup").toProperty();
  totalMonthlyCost = Bacon.combineWith(
    sumAll,
    [stream1, stream2]
  );
});

组合一组不断变化的属性的关键是flatMapLatest。您可以首先将当前的活动输入集表示为

inputsP = ...

由此,您可以映射到当前的属性集以像这样组合

propertiesP = inputP.map(i => i.asEventStream("change").map(() => i.value()).toProperty())

这是一个属性,其值是属性数组,或者在Haskellish中,您可以称它为Property (Array Property)。您可以将其展平为 Property Array,或包含值数组的 属性,只需

valuesP = propertiesP.flatMapLatest(Bacon.combineAsArray).toProperty()

最后,应用您的 sumAll 函数,如

valuesP.map(sumAll)

...假设 sumAll 将值数组作为其唯一参数。

当然,有人可能会争辩说有更简单的方法可以达到相同的结果。就像在整个容器元素上监听所有有趣的输入事件,并使用 JQuery 从容器中获取输入值,将这些东西提供给 sumAll。喜欢

$container.asEventStream("change blur keyup", "input")
  .map(() => $container.find("input").toArray().map(() => $(this).value()))
  .map(sumAll)

或者类似的东西。另见:http://baconjs.blogspot.fi/2013/02/chicken-egg-and-baconjs.html