如何使用FRP(和bacon.js)阻止事件周期

时间:2014-07-17 14:42:40

标签: javascript frp bacon.js

我已经设法在我的培根驱动的应用程序中创建一个循环,所以我需要一些关于如何打破它的建议。

让我们说我们有几个属性带有一些应用程序的状态。这个状态应该通过HTML5 History API(pushState)存储,因此我将这些属性组合到一个对象上并在其上执行pushState。但是,我还需要覆盖popstate个事件,所以在每个popstate(后退按钮等)上,我将状态对象拆分回单个属性并将它们注入到原始流中。

现在我已经有了一个周期:因为那些属性流是我从第一个位置获得pushState的相同流,所以再次调用pushState,复制堆栈上的状态并使后退按钮无用。

这当然是我的错误,但是,除了将每个属性流分成两个并在pushState / popState特定情况下将它们组合起来之外,我没有看到一个好的解决方案。但这似乎相当不优雅 - 是否有任何规范的方法来避免这种循环?

1 个答案:

答案 0 :(得分:1)

我提出的最优雅的解决方案是在推送新状态之前检查当前状态。如果它们是相同的,则什么都不做:

// state properties
var foo = ...;
var bar = ...;

// write
var history = Bacon.combineAll(makeHistoryState, foo, bar);

history.onValue(function (v) {
    if (!_.isEqual(history.state, v)) {
        history.pushState(v);
    }
});

// read
window.addEventListener("popstate", function(event.state) {
    foo.set(extractFoo(event.state));
    bar.set(extractBar(event.state));
});

免责声明:我自己没有测试

编辑:将全局状态作为单个属性时,将其保存到历史记录API中;一切都很简单。你可以利用Bacon.Model镜头功能