2012-11-12 8 views
6

Próbuję wykonać animowane przejścia między łączeniem różnych gniazd. Wiem, że istnieją metody takie jak willInsertElement, didInsertElement lub willDestroyElement w klasie Widok, które można przesłonić, ale nie można odroczyć dołączania, a zwłaszcza usuwania elementu. Próbowałem zastąpić inne metody, ale widok klasy jest skomplikowany, aby zrozumieć, jak to działa. Wpadłem na pewien pomysł:Animowane przejścia widoków. Jak odroczyć usunięcie lub wstawienie elementu?

jsfiddle example

AnimationHelper = Ember.Object.extend({ 
     isPreviousViewFadedOut:false, 
     nextViewToFadeIn:null, 
     triggerManually: true, 
     setNextViewToFadeIn:function (view) { 
      if (this.nextViewToFadeIn) { 
       if (this.hasObserverFor('isPreviousViewFadedOut')) { 
        this.removeObserver('isPreviousViewFadedOut', this.nextViewToFadeIn, 'fadeInCallback'); 
       } 
      } 
      this.nextViewToFadeIn = view; 
      this.addObserver('isPreviousViewFadedOut', this.nextViewToFadeIn, 'fadeInCallback'); 
     } 
    }); 

    AnimatedView = Ember.View.extend({ 
     didInsertElement:function() { 
      this.$().hide(); 

      if (AnimatedView.aHelper.get('triggerManually')) { 
       AnimatedView.aHelper.set('isPreviousViewFadedOut', true); 
       this.fadeInCallback(); 

       //next time we don't want call fadeInCallback manually 
       AnimatedView.aHelper.set('triggerManually', false); 
      } else { 
       AnimatedView.aHelper.setNextViewToFadeIn(this); 
      } 
     }, 

     fadeInCallback:function() { 
      if (AnimatedView.aHelper.get('isPreviousViewFadedOut')) { 
       this.$().fadeIn(1000); 
      } 
     }, 

     willDestroyElement:function() { 
      AnimatedView.aHelper.set('isPreviousViewFadedOut', false); 
      var clone = this.$().clone(); 
      this.$().replaceWith(clone); 

      var that = this; 
      clone.fadeOut(1000, function() { 
       $(this).remove(); 
       if (AnimatedView.aHelper.nextViewToFadeIn == that) { 
        AnimatedView.aHelper.removeObserver('isPreviousViewFadedOut', 
         AnimatedView.aHelper.nextViewToFadeIn, 'fadeInCallback'); 
       } else { 
        AnimatedView.aHelper.set('isPreviousViewFadedOut', true); 
       } 
      }); 
     } 
    }) 

    AnimatedView.reopenClass({ 
     aHelper:new AnimationHelper() 
    }) 

Wydaje się działać prawidłowo, ale jest to prawdopodobnie bardzo zły projekt. Czy istnieje lepszy sposób osiągnięcia podobnego efektu? a może całkowicie się mylę i powinienem spojrzeć na problem z zupełnie innej perspektywy? na przykład czy animacje w widoku, które owija inny widok itp.?

+0

Ta prezentacja może być pomocna: https://speakerdeck.com/machty/ember-meetup –

Odpowiedz

0

Wystąpiła prośba o pociągnięcie po chwili, która została scalona z wzorcem, która dodała kilka dodatkowych haczyków do Em.ContainerView, co pozwoliłoby na asynchroniczny okres przejściowy między dwoma widokami w gniazdku, ale ta zmiana została przywrócona wkrótce po niej. powodując błędy i nie będąc naprawdę dobrze omawianym podejściem pozwalającym na przejście między dwoma widokami wylotów.

Zespół firmy Ember ostatnio skupiał się na tym, aby naprawdę łatwo było powiązać widoki aplikacji z routerem za pośrednictwem gniazd typu one-view-a-a-time, a taki system tak naprawdę nie ułatwia rób to, co chcesz zrobić. Prawie na pewno, jeśli te przejścia są dla ciebie cenne, nie używaj w ogóle gniazdek i zamiast tego ręcznie twórz/dołączaj/animuj widoki samodzielnie podczas wchodzenia i wychodzenia. Być może rdzeń Ember w pewnym momencie przyjrzy się temu problemowi, ale nie spodziewałbym się tego przed nadchodzącą wersją 1.0.

Jestem przekonany, że ostatnio opublikowana aplikacja Yapp zbudowana w Ember przyjął podejście polegające na posiadaniu stanu dla każdego przejścia pomiędzy każdym stanem "lądowania" i nie korzystał w ogóle z outlet s. Aplikacja jest tworzona przez pewnych inteligentnych ludzi i radzi sobie całkiem nieźle, więc z pewnością wydaje się, że masz rację.

Powiązane problemy