Closed alecdotninja closed 4 years ago
This does enable some good use cases, allowing children to call up to parental behavior without having to know about the internals of the parent. I like what it enables. If we are going to allow having nested components a la React, then we need to support handling events up the tree from where they occur.
This just made me think of something. Could a motion that is mapped on a parent (e.g. map_motion :increment
) but triggered on a child component (e.g. <button data-motion="increment">
) be handled by the parent component? Presumably event bubbling would allow it to occur but is there anything preventing it from working?
Could a motion that is mapped on a parent [...] be handled by the parent component?
No, if the child component is also a Motion component, it will receive the motion from the button and the parent will not.
Presumably event bubbling would allow it to occur but is there anything preventing it from working?
All the usual DOM bubbling of the event applies, but there isn't anything like that for motions. For example, a parent component could put data-motion="click->increment"
on a div wrapping the child component and find out about the click event on the nested button that way, but there is no way for it to observe that the increment
motion is being triggered on the child.
The event bubbling makes sense to me because clicking a button in a div is necessarily also clicking the div. I'm not sure a similar thing makes sense for motions though ("incrementing" a nested component isn't necessarily the same thing as "incrementing" the parent, for example).
This PR comes out of a discussion in #22. ~I'm leaving it draft for now because I am not sure this is actually something that we want to do.~
Currently, the only way for a child component to communicate with a parent is with broadcasts. This works well when the purpose of communication is to signal that an external resource (like a model) has been updated, but it gets a bit awkward when the goal is to communicate something specific about the UI state of the page (like a form being "finished"). In the latter case, you need to generate and pass around a unique topic name for the broadcasts to ensure any changes are scoped to that user's view.
This introduces a new API ("callbacks" for now) that tries to make this a little less cumbersome.
Parent components can expose a method as a callback to their children using
bind
(which for ergonomics can be called both in the component class and the template):Child components can receive the callback created by
bind
just like any other state, and trigger it using thecall
method:This short example is a bit contrived (Why not eliminate
ButtonComponent
completely or make it presentational and use a motion directly onCounterComponent
?), but I think this is a reasonable feature to want in general.That said, I have a few concerns:
bind
the right syntax for creating callbacks?My intention is that this PR can serve as a place for a public discussion about whether adding this feature to Motion is a good idea.