2015-06-24 38 views
8

Ho un app che appare fondamentalmente come questoLe migliori pratiche per l'animazione più ui-viste come uno

<div ui-view="header"> 
<div ui-view="main"> 
<div ui-view="footer"> 

Ora, il piè di pagina rimarrà lo stesso per tutti i diversi stati della app, ma l'intestazione cambierà in alcuni stati, ma anche condividere contenuti in molti stati. L'unico ui-view che cambierà in tutti gli stati è ui-view="main".

Attualmente la mia $stateProvider assomiglia a questo (piè di pagina non ancora implementata):

app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { 
    $stateProvider.state('root',{ 
     url: '', 
     abstract: true, 
     views: { 
     'header': { 
      templateUrl: appHelper.views+'/header.html', 
     }, 
     } 
    }) 
    .state('root.home', { 
     url: '/', 
     views: { 
     'header': { 
      templateUrl: appHelper.views+'/header.html', 
     }, 
     '[email protected]': { 
      templateUrl: appHelper.views+'/home.html', 
      controller: 'HomeController as homeVm', 
     } 
     }, 
     resolve: { 
     posts: function(dataService) { 
      return dataService.getPosts(); 
     }, 
     artists: function(dataService) { 
      return dataService.getArtists(); 
     } 
     } 
    }) 
    .state('root.artist', { 
     url: '/artist/:slug', 
     views: { 
     '[email protected]': { 
      templateUrl: appHelper.views+'/artistHeader.html', 
      controller: 'ArtistController as artistVm', 
     }, 
     '[email protected]': { 
      templateUrl: appHelper.views+'/artist.html', 
      controller: 'ArtistController as artistVm', 
     } 
     }, 
     resolve: { 
     artist: function($stateParams, dataService) { 
      return dataService.getArtist($stateParams.slug);  
     } 
     } 
    }); 
}]); 

Fin qui, tutto bene. Ma ecco il trucco. Durante le transizioni voglio animare tutti i ui-view s come uno. Per rendere le cose un aspetto coeso nel mio caso (è un'animazione dissolvenza) vorrei metterle in un div wrapping e fare in modo che il div diventi dissolvenza/dissolvenza (farlo su ogni diverso ui-view causerà tutti i tipi di bruttezza).

Qual è la migliore pratica in questo scenario?

Li ho avvolti in un ui-view e lo collego in qualche modo nello $stateProvider (nidificato ui-view s?). Ci sono altri modi per farlo? Posso ascoltare $stateChange e applicare classi al mio wrapper come ngAnimate con un ui-view? (svanire poi attendere fino a quando non svanisce completamente con una risoluzione riuscita prima di dissolversi).

Dai miei sforzi su Google sembra che ui-view sia molto preferito quando si gestiscono le animazioni del tipo di transizione.

+0

Le animazioni negli eventi '$ stateChangeStart' e' $ stateChangeSuccess' hanno alcuni effetti collaterali, quindi evitali (al momento). Fino a quando l'ui-router non avrà un modo migliore per gestire la promessa di transizione oltre alle animazioni di 'event.preventDefault()' tramite JS sarà complicato. Eseguire tre 'ui-view' e animarli tutti in modo sincrono non dovrebbe essere un problema attraverso il puro CSS. Dai uno sguardo alla sezione delle domande frequenti sugli ui-router, c'è una sezione dedicata all'animazione delle transizioni. –

+0

Mentre l'animazione è sincrona, causa problemi con il disegno poiché l'intestazione '' è fissata nella parte superiore della finestra durante lo scorrimento. Quando inizia la dissolvenza, rivelerà il contenuto di 'main' sotto il quale non è desiderato. Con un wrapper questo ovviamente non è un problema in quanto svanirà come un singolo elemento .. – INT

risposta

2

... Durante le transizioni, desidero animare tutti i punti di vista come uno. Per rendere le cose coerenti nel mio caso (è un'animazione dissolvenza) Mi piacerebbe metterle in un div wrapping e fare in modo che div diva fade out/dissolvenza in (farlo su ogni diversa interfaccia utente causerà tutto tipi di uguaglianza ).

Qual è la migliore pratica in questo scenario?

Opzione 1: Uso ganci eventi $stateChangeStart e $stateChangeSuccess

Questo approccio avrebbe alcuni effetti collaterali, come @ David accennato nei commenti. Quindi evitalo fino a quando lo ui-router non ti offre un modo migliore per gestire la promessa della transizione di stato. Attualmente si basa su event.preventDefault() per impedire che la transizione accada.

Fondamentalmente, ui-router genererà la visualizzazione del cambio di itinerario ui-view contemporaneamente alla visualizzazione in ingresso. Quindi quello che ottieni è il precedente ui-view ancora visibile mentre il successivo ui-view viene visualizzato e se stai animando la visualizzazione, ci sarà quella durata della transizione di sovrapposizione tra la vecchia visualizzazione e la nuova. Si dovrebbe guardare in tenendo a bada sulla rendendo la nuova interfaccia utente con vista fino a quando il vecchio è finito animare out (prima di animare la nuova in)

Per ragioni analoghe, avvolgendoli in un altro ui-view e aggancio in su nella $stateProvider sarebbe non essere saggio

Opzione 2: CSS basato animazioni (consigliato)

io per lo più vado con le transizioni CSS based e si può raggiungere questo obiettivo sia con

  • l'assegnazione di una classe CSS comune a ogni ui-view e l'applicazione di animazione in quella classe
  • o allegando i tre ui-view in un <div> (se proprio necessario) e applicare l'animazione su di esso.

In entrambi i casi, si tratterebbe di tutto il ui-views come una singola entità e l'animazione li renderebbe le cose più coese.

HTML:

<div ui-view="header" ></div>  
<div ui-view="main" ></div> 
<div ui-view="footer" ></div> 

CSS:

[ui-view].ng-enter { 
    animation: fadein 2s; 
} 

@keyframes fadein { 
    from { opacity: 0; } 
    to { opacity: 1; } 
} 

Ecco un lavoro plunkr, sulla base di caso d'uso in cui, ho uno stato astratto root e tre stati annidati root.home, root.artist e root.band. Mentre lo ui-view='main' viene modificato in tutti gli stati, ui-view='footer' non cambia in nessuna e ui-view='header' modifiche per lo stato 'root.artist'. Il fatto che si stiano utilizzando classi basate su CSS .ng-enter e .ng-leave per attivare le animazioni, si risolvono tecnicamente i problemi con l'approccio precedente.

$stateProvider 
     .state('root',{ 
      abstract:true, 
      views:{ 
       'header':{ //absolutely targets the 'header' view in root unnamed state. 
       templateUrl:'header.html' 
       }, 
       'footer':{ //absolutely targets the 'footer' view in root unnamed state. 
       templateUrl:'footer.html' 
       } 
      } 
     }) 
     .state('root.home',{ 
      views:{ 
       '[email protected]':{ 
       templateUrl:'main.html' 
       }, 
      }   
     }) 
     .state('root.artist',{ 
      views:{ 
       '[email protected]':{ 
       templateUrl:'artist-header.html' 
       }, 
       '[email protected]':{ 
       templateUrl:'artist-main.html' 
       }, 
      }   
     }) 
     .state('root.band',{ 
      views:{ 
       '[email protected]':{ 
       templateUrl:'band-main.html' 
       }, 
      }   
     }) 
+0

Hey @NLN, grazie per la tua ampia risposta! Ho aggiornato un po 'il tuo plunkr per riflettere meglio il problema che sto affrontando: http://plnkr.co/edit/mLUqKIjby9WGZ60k56ym?p=preview Con la dissolvenza devi anche posizionare in assoluto i div che lo rendono un po' difficile con il footer. Quindi voglio essere in grado di animare il div padre piuttosto che le singole div (come puoi vedere le div di colore rosso e blu si sovrappongono, che non sembra affatto buono quando l'opacità calcia). – INT