Cycle.js 驱动程序中可以有多个 DOM 对象吗?

Can there be more than one DOM object in the Cycle.js drivers?

到目前为止我找到的所有 Cycle.js 示例,在 run(main, drivers)drivers 参数中使用一个名为 "DOM" 的 DOM 对象].是否可以有多个对象,例如,一个名为 "DOM1" 而另一个名为 "DOM2"?这样做的目的是在单个 HTML 页面中控制两个独立的动态 DOM 区域,以便在 index.html 中静态定义第三个 DOM 区域,并将其夹在中间在 DOM1 和 DOM2 之间。

作为附带问题,我看到的示例通常针对 ID 为 #app#main-container 的 HTML div,然后接收器是用 @cycle/dom div 函数定义,因此在 div 中创建了一个不必要的 div AFAICT。我还没有找到关于应该如何定义虚拟节点的明确解释或参考。假设上面的 DOM2 以 HTML form 元素为目标,并且应该包含两个 input 元素。它 像所有示例一样以 div 开头,还是可以直接在 .map 调用中定义 input,以及如果可以,怎么做?

没有什么可以阻止您在应用程序中使用 DOM1DOM2 接收器。 bloodyKnuckles 的例子完美地说明了这一点 https://esnextb.in/?gist=b54baa4131974b7f12d190fb63be8aeb

话虽如此,我不确定我是否真的明白这样做的意义。如果是性能问题,我认为将应用程序的呈现拆分为两个 DOM 驱动程序不会有太大好处。虚拟 DOM 库(在 cycle 的例子中是 snabbdom)被定制来识别 DOM 的片段,这些片段没有改变,只更新后者。

如果这是责任问题(DOM 的 2 个部分有非常不同的用途),那么我宁愿创建两个不同的循环应用程序,它们都在 DOM 的不同部分呈现。 (然后在主文件中调用 run 两次)

function app1(sources) {
  return {
    DOM: xs.of(div("hello from app1"))
  }
}


function app2(sources) {
  return {
    DOM: xs.of(div("hello from app2"))
  }
}

run(app1, {
  DOM: makeDOMDriver("#app1")
})


run(app2, {
  DOM: makeDOMDriver("#app2")
})

这样您就可以清楚地分离两个应用程序的关注点。

现在回答您的问题,即为什么需要将一块虚拟 DOM 包裹在 div 中。这是因为一块虚拟 DOM 必须有一个 单根 元素。换句话说:一段虚拟 DOM 必须是独立的(就像一个 HTML 文档只有一个 <html> 元素,它是根)。 实际上,这是一个很好的约束,因为它迫使您拥有独立的组件。在您给出的示例中(带有 <input> 字段),返回这样的 vDOM 绝对没有问题:

DOM: xs.of(input(/*...*/))

但是如果你的组件有一个input和一个label,那么你需要将它包装在另一个vNode

DOM: xs.of(div([label(/*...*/), input(/*...*/)])