【问题标题】:Cycle.js app uncaught type errorCycle.js 应用程序未捕获类型错误
【发布时间】:2016-02-26 12:23:42
【问题描述】:

我正在努力学习Cycle.js,我必须说我觉得它很有趣。我正在尝试创建一个简单的应用程序,其中有一个input 和一个ul。每次向input 写入一些值并按回车键时,我想将新的li 添加到ul,但它失败并出现以下错误。

未捕获的 TypeError:observables[_name2].doOnError 不是函数

var view = function (state) {
    return CycleDOM.body([
        CycleDOM.input({ type: 'text', value: '' }),
        CycleDOM.ul({ className: 'text' },
            state.map(function (value) {
                CycleDOM.li({ innerText: value });
            }))
    ]);
};

var intent = function (DOM) {
    return DOM.select('input[type=text]').events('keydown').filter(function (ev) {
        return ev.which == 13 && ev.target.value.trim().length > 0;
    }).map(function (ev) {
        return ev.target.value;
    });
};

var model = function (action) {
    return action.startWith('');
};

var main = function (sources) {
    var actions = intent(sources.DOM);
    var state = model(actions);
    var sinks = {
        DOM: view(state)
    };
    return sinks;
}

var drivers = {
    DOM: CycleDOM.makeDOMDriver(document.body)
};

Cycle.run(main, drivers);

【问题讨论】:

  • 抛开程序逻辑,view()需要返回一个Observable,state.map(...)里面的函数也应该返回一些东西。

标签: javascript html rxjs cyclejs


【解决方案1】:

首先,很高兴看到人们对 Cycle 感兴趣!

您在这里遗漏了一些要点,这就是您遇到一些困难的原因。

您可能还没有完全理解反应式编程的概念。您应该阅读 Cycle 创建者的 The introduction to Reactive Programming you've been missing 并观看 his videos about Cycle。它们确实有助于了解 Cycle 的内部运作方式。

另外,您可以采用 Cycle 的命名约定,这真的很有帮助。流/observable 应该以 $ 结尾,例如

var click$ = DOM.select('a').events('click');

正如@juanrpozo 所说,您的主要问题在于您的view 函数,因为它返回一个虚拟树而不是可观察的虚拟树。 同样重要的是您要了解state 变量是可观察的,而不是javascript 数组。这就是为什么我认为你对 Rx 还不满意。您认为您正在映射一个数组,但实际上您映射的是一个可观察对象,因此返回另一个可观察对象,而不是数组。 但是由于 DOM sink 应该是一个 observable,这很完美,你只需要将你的 VTree 包装在 map 中:

var view = function (state$) {
    return state$.map(function (values) {
        CycleDOM.body([
            CycleDOM.input({ type: 'text', value: '' }),
            CycleDOM.ul({ className: 'text' }, values.map(function (value) {
                CycleDOM.li(value);
            }))
        ])
    };
}

另一个问题是您的state$ 管理。您必须了解state$ 是组件的连续状态流。在 stackoverflow 上很难解释这一点,但如果你阅读/观看我发送给你的资源,你会毫无问题地得到它。

我让你 a jsbin of your code 更正并更改了一点以更加尊重 Intent/Model/View 约定。

您还有其他错误,但这些是最重要的。

【讨论】:

  • 太棒了。是的,我仍在学习 Rx,但仍然很享受它。我知道我应该从view 函数返回一个Observable,但不确定如何映射ul 的子代。请问scan函数是做什么的?
  • 我刚刚运行了你的代码,它说values.map 不是一个函数。
  • scan 允许您应用累加器函数:github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/… 在这里您必须了解组件的状态实际上是一个字符串列表(数组)。什么定义了待办事项列表?这是要做的事情的清单。那是你的状态。在您的代码中,状态只是一个字符串。因此,为了维护和更新该状态,我们要做的就是累积一个字符串列表。这就是为什么意图是“我添加一个新条目”并且模型将此意图转换为“我将此新条目添加到现有条目”并且视图会显示它们
  • 您是从 jsbin 中获取代码还是仅获取了一小部分?由于它正在 jsbin 上工作,我假设您只使用了它的一部分,所以在您的情况下,values 可能不会被初始化(valuesnullundefined'')。这就是我代码中的startWith([]) 的用途。
  • 我似乎了解startWithscan 的重要性以及返回stream 的视图。谢谢@chadrien。我们可以在其他地方讨论更多这个概念吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
  • 2013-07-23
  • 2018-05-24
  • 1970-01-01
  • 2012-12-29
  • 2014-12-07
相关资源
最近更新 更多