Reputation: 1750
All the Cycle.js examples I've found so far, use a single DOM
object, named "DOM", in the drivers
argument to run(main, drivers)
. Is it possible to have more than one object, e.g., one named "DOM1" and another "DOM2"? The purpose of this would be to control two separate dynamic DOM areas within a single HTML page, in order to keep a third DOM area statically defined in index.html
, and sandwiched between DOM1 and DOM2.
As a side question, the examples I've seen typically target an HTML div
with an id of #app
or #main-container
, and then the sink is defined with a @cycle/dom
div
function, thus creating AFAICT an unnecessary div
within a div
. I haven't found a clear explanation or reference of how the virtual nodes are supposed to be defined. Say that DOM2 above targets an HTML form
element and that is supposed to contain two input
elements. Does it have to start with a div
as in all the examples, or can the input
s be defined directly in the .map
call, and if so, how?
Upvotes: 0
Views: 148
Reputation: 2583
There is nothing preventing you from having a DOM1
and DOM2
sinks in your app. bloodyKnuckles' example illustrate that perfectly https://esnextb.in/?gist=b54baa4131974b7f12d190fb63be8aeb
That being said, I am not sure I really see the point of doing this. If it's a matter of performance, I don't think you will gain much in splitting the rendering of your app into two DOMDrivers. The virtual DOM lib (in cycle's case snabbdom) is tailored to recognize pieces of DOM that haven't change from those which have and only updates the latter.
If it's a matter of responsibilities (those 2 pieces of DOM have very different purposes), then I would rather create two different cycle apps that both render in different parts of the DOM. (and then call run
twice in your main file)
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")
})
This way you have a clear separation of the concerns of both apps.
Now to answer your question about why a piece of virtual DOM needs to be wrapped in a div
. It is because a piece of virtual DOM have to have a single root element. Said otherwise: a piece of virtual DOM have to be standalone (just like an HTML document only has a single <html>
element which is the root).
It is, actually, a nice constraint to have because it forces you to have standalone components. In the example you give (with an <input>
field), there is absolutely no problem in returning a vDOM like this:
DOM: xs.of(input(/*...*/))
But if your component has an input
and a label
, then you will need to wrap it in another vNode
DOM: xs.of(div([label(/*...*/), input(/*...*/)])
Upvotes: 1