javascript - Fördröja borttagning av en vy så att den kan animeras


Säg att jag har en mall som visar en vy baserat på en egenskap:

{{#if App.contentsAreVisible}}
    {{view ToggleContents}}
{{/if}}

Detta område växlas av ett antal andra delar av användargränssnittet genom att ställa in App.set("contentsAreVisible", [true/false]);

Allt detta fungerar bra.

Men jag vill nu animera när vyn växlas. Att koppla in sig i didInsertElement fungerar för att animera visningen av området, men jag kan inte göra samma sak i willDestroyElement eftersom elementet tas bort så snart den funktionen returnerar, innan animationen har en chans att köras.

App.ToggleContents = Ember.View.extend({

    // this works fine
    didInsertElement: function(){
        this.$().hide().show("slow");
    },

    // this doesn't work
    willDestroyElement: function(){
        this.$().hide("slow", function(){
            // animation is complete, notify that the element can be removed
        });
    }
});

Finns det något sätt att tala om för vyn att skjuta upp borttagningen av elementet från DOM tills animationen är slutförd?

Här är en fiddle med ett interaktivt exempel: http://jsfiddle.net/rlivsey/RxxPU/

Svar #1

Du kan skapa en hide-funktion på din vy som tar bort vyn när callbacken är klar, se http://jsfiddle.net/7EuSC/

Styrhandtag:

<script type="text/x-handlebars" data-template-name="tmpl" >
    <button {{action "hide" }}>hide</button>

    This is my test view which is faded in and out
</script>

JavaScript:

Ember.View.create({
    templateName: 'tmpl',

    didInsertElement: function() {
        this.$().hide().show("slow");
    },

    _hideViewChanged: function() {
        if (this.get('hideView')) {
            this.hide();
        }
    }.observes('hideView'),

    hide: function() {
        var that = this;
        this.$().hide("slow", function() {
            that.remove();
        });
    }
}).append();

Svar #2

Jag vet att detta redan har rätt svar, men jag tänkte att jag skulle lägga upp något liknande ifall någon annan hittar detta genom Google som jag gjorde.

En av mina appar har en 'detalj'-sektion som alltid har samma innehållsbinding men ändrar mallen för visnings-/redigerings-/etc-lägen.

Eftersom jag använder rerender() för att uppnå detta och vill att vyn ska blekna ut och sedan in igen så att det döljer eventuell glitchighet i rerender-funktionen (samt gör att det ser bra ut) har jag omslutit det i en för animationssyften.

<script>
_templateChanged: function(){
  self = this;
  $('#effects-wrapper').fadeOut('fast',function(){
    self.rerender();
    $(this).fadeIn('fast');
  });            
}.observes('template')
</script>

och

<div id="effects-wrapper">
{{App.Views.Whatever}}
</div>

Kanske inte det bästa alternativet, men kanske också användbart för någon