willDestroyElement hook

Just curious about the willDestroyElement hook.

If I want to do some work such as animate the dismissal of a UI element. Seems like willDestroyElement is the proper place to do that.

But also curious why there is not a didDestroyElement hook to provide semantic symmetry to didInsertElement hook? Truly and utterly past tense. Is it because essentially there is nothing to reference anymore in memory at this point?

If I had a behavior that is indeterminate in length of time say but I always want to do it asynchronously and without blocking UI is it even possible to use willDestroyElement?

I guess I am not sure about the specific use case for this.

Primarily, I want to animate the closing of a modal dialog component and it seems like willDestroyElement is the place to do that. But if there is a problem in the function that implements this, then that means that the UI element can get stuck in the DOM and might not actually be removed.

Is it possible to actually perform an animation in willDestroyElement?

When I tried to do something like this, the animation didn’t show because the willDestroyElement returns immediately, while the animation runs async.

Perhaps a promise/callback system could be added to facilitate asynchronous operations in the view lifetime hooks…?

2 Likes

@eccegordo Ember provides no animation or transition specific hooks. There are future plans to provide them, but nothing built-in today. willDestroyElement and didInsertElement are sync operations, absolutely.

https://github.com/billysbilling/ember-animated-outlet has been mentioned by the core team as a candidate for inclusion in Ember proper. I’ve heard good things about it personally, but have never used it.

Other options:

  • Use ContainerView objects, which give you programatic control over appending and removing child views.
  • Use willDestroyElement and clone the element before it is destroyed. Ember.js routing, outlets and animation - Stack Overflow
  • Use this.render to render the view you want to animate into an outlet, and then perform the dismissal transition before calling disconnectOutlet. Or use a pivot route for the transition.

I hope that helps with a direction.

1 Like

@Rengers and @mixonic thanks for the info good to know. I figured as much about the synchronous behavior. I am wondering can you cancel the destroy operation? Presumably by returning false from willDestroyElement hook. What about the inverse, if you want to cancel the insert element. Is there a hook willInsertElement.

What is important to me is the past, present and future tenses are semantically meaningful.

Animations is certainly one use case. But also just trying to understand the lifecycle around a component. There are specific use cases where I want to have arbitrary control over the lifecycle of a component or multiple components on a single page/view/template/route/controller/state.

I guess I am thinking a state machine within the state machine that is the router. If that makes any sense.

This is definitely not true. Basically, by the time the view is instantiated there is no chance for you to stop the view from rendering. There is no willInsertElement, but the point is moot since didInsertElement is sync. You cannot control views being rendered or not rendered at the view level. You cannot delay the rendering.

If you need arbitrary control over a part of the DOM, I suggest named outlets. http://blog.safaribooksonline.com/2013/09/10/ember-js-outlets/ Today, that is the only option available without diving into Ember itself.

OK, thanks for the clarification. So it seems that a workaround is to catch any “exit” behavior in a custom method in the component or controller. Basically wrap any potential calls to the destroy or remove methods with some additional functionality and validation that makes sense for the component or application.

I have played a little with named outlets but was more confused than illuminated. The whole renderTemplate stuff was too confusing to me the first time I looked at it. Will give it a closer look. Thanks for the link.

By the way the potential use cases I have in mind:

  • Custom modal dismissal with validation
  • Complex D3 charts with interactive and dismissible elements
  • Games that have DOM elements come and go without changing urls or router state.

The first two of your items could be handle with named outlets. Also see the willTransition hook on routes. That would give you a chance to trigger and wait for transitions as you leave a given route.

If you have a stage of items moving around and popping in and out of existence, I suggest looking at ContainerView to manage them programatically.

2 Likes

Look here