Yesterday, we published a post about limitations of the Om model. Several people responded, including Peter Jaros, Vesa Marttila, Brian J. Rubinton, and Mark Stang. A common suggestion was to use a core.async channel, which is essentially what we did. This post gives more details about the solution we chose.
React, and by extension Om, has a nice simple hierarchical model for how applications are structured. You have a hierarchy of components that each divvy up slices of their own state to their child components. And they decide on the basis of the portion of state that they receive from their parent which children they should have and what chunk of state they should pass on to them. In this model the DOM hierarchy mirrors the component hierarchy. Each component is required to produce a DOM node and each of its children must produce a descendant DOM node. For the most part, this works very well and most components can be implemented entirely within this model.
There are however some kinds of components that cannot be wholly conformed to this model. The particular kind I’m worried about is modals as described by my cohort in an earlier post. Even more particularly I’m concerned with modals that are strictly logical children of the component that spawned them (e.g. a dismissal confirmation modal on a notification component). Because of the way positioning and z-indexes work in the DOM, you need modals to at least be peers of the highest level positioned elements. This means that they can’t necessarily be proper child components of the component that spawned them. And if we lose the parent child relationship, not only do we lose the nice correspondence between logical hierarchy and DOM hierarchy, we also lose the ability for a parent’s (or grandparent’s) decision to stop building its children to imply that modal should also go away.
There are certainly ways around this. The way we eventually chose was to have a high level component that consumed a core.async channel through which could be passed maps of component, cursor and a channel that could be used for communication back to the modal-creating component. Then if the modal creating component is removed from the DOM, it can, in
IWillUnmount, close the communication channel, which triggers the removal of the modal. And I’m sure there are other, better ways of doing it. It is certainly not an insurmountable problem. But I feel it would be nice if we didn’t have to resort to these tools of inter-component communication for what, logically, is just a parent-child relationship.
This probably isn’t a practical suggestion or even particularly well thought out, but it would be nice if you could provide
om.core/build a reference to another DOM node and let the particular component being built be a descendant of that node, rather than its logical parent’s DOM node. It would at least solve this difficulty (probably at the expense of creating others).
You can contact us at firstname.lastname@example.org Or join the conversation on twitter:
— Altometrics, Inc. (@Altometrics) April 21, 2015