mithril.js
mithril.js copied to clipboard
Add a special vnode that allows manipulating attributes on a raw event target reference
Mithril version:
Platform and OS:
Project:
Is this something you're interested in implementing yourself? Yes
Description
We should add a special primitive, say m.link(value, {...}), that lets us simply set attributes on the element. Examples:
m.link(window, {onscroll() { ... }})for scrollm.link(document, {onmouseup() { ... }, onmousemove() { ... }})for drag and dropm.link(document, {title: ...})m.link(window, {scrollX, scrollY})
The event handlers would of course autoredraw as existing Mithril-tracked event handlers do.
Why
I find myself so often wanting to mount and unmount event handlers within UI trees. This would make it such that I could just do it declaratively. It'd also provide a clean way to set the document's title and so on as well.
Edit: Here's a couple userland implementations of the events component of this.
- A full implementation of just the events part using an
m.patchsuggested on Gitter - A minimal form of the above that just does one event + target + callback combo, without even redraw logic
It's actually surprisingly complex in practice to wire up, even for just events. This proposal suggests a superset, and in total would probably be at worst around the size of the full events implementation above.
Possible Implementation
- Add a condition to
setAttrto avoid thesetAttributefallback and just always set the value for event targets that don't extendNode, and updateremoveAttras appropriate as well. - Add logic for the node to simply invoke
setAttrs/removeAttrsas appropriate. - The factory is obvious.
Open Questions
- Should we even add this? It's pretty easy for us, and provides a large amount of functionality for very little cost, but of course it's also entirely doable in userland.
- The name is kinda loaded. I thought of
m.bind, but that's even worse, and I don't want some long, unwieldy name for this, either. I could totally use some more ideas in this department.
what about just m(body, { ... }) 🙈
I considered that, but I was hoping to avoid discussions on how children should be added/removed from existing nodes that are already live with potential children. Edit: I would be okay with opening up that prospect, though. (I could see React Helmet-like use cases for one. I could also see the value of adding inline style sheets linked to components, in effect using Mithril as a resource loader.)