creationix / domchanger

dombuilder that applies diffs only to the real dom
72 stars 17 forks source link

after render hook? #4

Open leeoniya opened 9 years ago

leeoniya commented 9 years ago

Hi,

How would you suggest to handle a case when you need to interact programatically with an element or component after it is rendered. For example rendering a <textarea> with a value and setting the cursor position or selection range within it after it has been rendered?

Is there a post-render hook that provides a reference to the element's node to allow for this?

thanks!

creationix commented 9 years ago

What's the use case? Rendering is synchronous.

leeoniya commented 9 years ago

sorry premature submit, read above.

async rendering is another issue i will open later :), like returning a Promise from render or a [Promise, placeholder]

leeoniya commented 9 years ago

perhaps use the same strategy as refs. and pass an object of tagged nodes to a pluggable afterRender callback.

EDIT: if this callback fires on both initial render and refresh, probably passing in isInitial would be useful as well when invoked

leeoniya commented 9 years ago

another use-case is setting .value on a <select> node instead of re-rendering an option[selected] every time.

another is setting a form element's focus.

creationix commented 9 years ago

In dombuilder (the previous generation to domchanger), I had a special $ property that was a function to call when a node was rendered to the dom https://github.com/creationix/dombuilder/blob/master/dombuilder.js#L71-L72

I vaguely remember something being done here, but can't find it. The raw "el" node type was added when I was using codemirror in an app. (See http://desktop.creationix.com/ and https://github.com/creationix/tedit/blob/master/src-minimal/ui/code-mirror-editor.js#L18-L31)

leeoniya commented 9 years ago

coincedentally, i'm writing a toy in-browser IDE with tabbed nav, session restore, status bar and codemirror to test domchanger. this involves restoring codemirror selections, cursor pos, history state. file contents are loaded async from the server, so a way to do deferred render via Promises will need to be figured out.

a per-element afterRender(el, isInitial) callback would be ideal, but a single callback at component level would be okay too...maybe even both.

creationix commented 9 years ago

I think this afterRefresh hook will help. I can also add a per-element hook for rendered elements like dombuilder had if that is helpful.

I'm still not sure why domchanger should have to know anything about the promises for fetching your data. Simply call refresh or emit an event when your promise finally gets fulfilled.

leeoniya commented 9 years ago

yes, this works well.

i think isInitial would be useful to know since render is called as both a pseudo-constructor to inject params into the component's closure as well as a refresh re-renderer.

EDIT: i may be missing something here, so please clarify if any of this is incorrect EDIT 2: extra stuff in this comment moved to own issue (#5)

leeoniya commented 9 years ago

i do think that having an afterRefresh(isInitial) per element would be useful and would make for cleaner strings since tagging would no longer be compulsory and the setup would be more declarative and in-place.

creationix commented 9 years ago

I have wished a few times that the component had some sort of initialization parameters apart from the render data. I'll have to think about to fit this in.