reflex-frp / reflex-dom

Web applications without callbacks or side-effects. Reflex-DOM brings the power of functional reactive programming (FRP) to the web. Build HTML and other Document Object Model (DOM) data with a pure functional interface.
https://reflex-frp.org
BSD 3-Clause "New" or "Revised" License
352 stars 141 forks source link

postBuild fires before the document fragment is added to the DOM #110

Open albertov opened 7 years ago

albertov commented 7 years ago

I've migrated a reflex binding for OpenLayers to the development branch of reflex-dom and I've noticed that I can no longer depend on the "postBuild" event to perform some initialization on the OpenLayers side which needs to be done when the element has been attached to the DOM and sized properly.

I've worked around it by polling the document until my element is added, like this, but with the stable version of reflex-dom I could simply do this.

Is this change intentional? If so, is there a better way I can use to be notified when an element I create is added to the DOM? If not I can try to submit a fix...

Cheers

ryantrinkle commented 7 years ago

The purpose of the postBuild event is just to fire as soon as possible after the builder action has finished running, so this is the intended behavior. It's not meant to be related in any particular way to whether the widget is mounted in the DOM, and, even in previous versions, there were situations where it would fire before something was mounted. The change to attachWidget was made because it (dramatically) improves performance.

What I'd like to do is add some proper lifecycle tracking to reflex-dom. Do you have any thoughts on what the ideal interface would look like to you?

albertov commented 7 years ago

So my understanding is that postBuild has nothing to do with the relationship between reflex widgets and the DOM but with the lifecycle of the reflex widgets themselves, right?

Then it would be very useful to add (an)other event(s) which track(s) relationship with them DOM as there are many cases when interfacing with foreign libraries that you need this. I can think of many similar use-cases like this one with other foreign libraries, (ie: to tell a widget to update its size once the dimensions are known by the layout engine).

What I'd like to do is add some proper lifecycle tracking to reflex-dom. Do you have any thoughts on what the ideal interface would look like to you?

I think my use case would be covered by a 'postMount' event which is made available like 'postBuild' is and was fired right after this line. I'll try to implement this as a POC if I have some spare time today...

Probably a 'preUnmount' event would be useful too to tell the foreign widget to perform any cleanup it needs to.

ryantrinkle commented 7 years ago

What do you think about something like a Dynamic that represents the current state? Then, the 'updated' state could be used to detect state changes.

albertov commented 7 years ago

That would work too. Anything is better than polling.

On Mon, Oct 31, 2016 at 3:30 PM, Ryan Trinkle notifications@github.com wrote:

What do you think about something like a Dynamic that represents the current state? Then, the 'updated' state could be used to detect state changes.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/reflex-frp/reflex-dom/issues/110#issuecomment-257308859, or mute the thread https://github.com/notifications/unsubscribe-auth/AA00C2dg7UznVskqZGOYR3q6KIZ8wjRdks5q5fuggaJpZM4Kke6j .

qrilka commented 7 years ago

@ryantrinkle I have stumbled upon similar problem (I need to run JS with the resulting DOM) and I have resolved it using the following code - https://www.reddit.com/r/reflexfrp/comments/5dnnsr/is_there_any_way_to_run_an_action_after_all/daaprnn/ Is this approach a valid one? As for 'updated' - could you explain it a bit? I didn't find any way to determine DOM updates after Dynamic upate other than postGui? How could it be done only with Dynamics (if that's what you propose)

qrilka commented 7 years ago

and actually that code doesn't work anymore with the current (github) reflex-dom version

nh2 commented 5 years ago

I'm having this problem too. Adding a text box, and want to .focus() it afterwards.

Right now I can only do it with racy setTimeout(..., N) delays.

eskimor commented 5 years ago

I have some hacky delay 0.1 in the code right now too, to work around this. Having a notification when an elment gets removed would be super cool too, for example to write bindings for material-design, which makes use of such events.

3noch commented 5 years ago

https://github.com/reflex-frp/reflex-dom/pull/152 was an attempt at adding this feature but it had negative performance impact.