aurelia / templating

An extensible HTML templating engine supporting databinding, custom elements, attached behaviors and more.
MIT License
116 stars 104 forks source link

Views are removed in a synchronous way causing issues with animations #596

Open tomasbonco opened 6 years ago

tomasbonco commented 6 years ago

I'm submitting a bug report

Current behavior: The problem shines best if you have a list of items and removing an item from the list should be animated (let's say fade-out). An animation is basically (from the perspective of Aurelia) just a promise returned from Animator, that takes some time to get resolved. Once you remove two items from a list in a short period of time, you can clearly see that Aurelia Templating doesn't register the second item being removed until Promise returned for the first item is not resolved.

Implications:

  1. Animations do work the other way then you think they do. Imagine you remove 3 items from the list in 600ms sequence. Fade out animation takes 1 second. How long will it take for all animations to finish? You would guess 1.2s (till the third animation is started) + 1s ( duration od third animation) = 2.2s, right? Wrong!

Picture: http://au.comper.sk/au-timing.png

Explanation: Aurelia waits for the end of the first animation, then fires the second, and then fires the third. But that is not always true if you do a simple tweak in timing (600ms becomes 500ms sequence) you might get into the state where the second and third animation are fired together.

  1. (Note: There is source code attached for this one.) You are unable to connect animations on Animator level (where it makes sense the most). Imagine (and this is a real case I have a struggle with) you have a list of items, like a list of social networks. Your job is to first let the user select all social networks she wants to publish her post to, then do the posting and then animate all networks at once. So what you really have to do is to synchronous asynchronous tasks. But you get data of available networks from the server, so you once the post was posted on given network, you get a list with that one network missing. What you would like to do is in Animator you return a Promise, that is composed of two promises: 1. wait for other networks to be removed, 2. fade-out.

But you can't do that. The first animation will be waiting for other elements. But the second removed element will never trigger removed state because Aurelia is waiting for the first promise. That makes it closed loop, where two items are waiting for each other.

I made a demo for that: http://au.comper.sk/ Source code: https://github.com/tomasbonco/aurelia-animator-bug (it intentionally doesn't solve all the problems, so the code is short and it should be easy to get into the picture).

Expected/desired behavior: In an ideal world, items won't be removed in series, but in parallel. So when binding reports item is removed, templating removes the item (even thou other item is being removed at the same time).

Alexander-Taran commented 6 years ago

interesting