2015-09-03 19 views
5

Versione cortaassicurarsi che i cambiamenti DOM sono finiti prima di transizione

Quando le transizioni ui-router ad una nuova vista (utilizzando ngAnimate in qualche modo che non capiscono fino in fondo), si aggiunge alle classi ng-leave e ng-leave-active alla vista corrente. Aggiunge anche le classi ng-enter e ng-enter-active alla vista successiva. Il problema è che la transizione è iniziata prima che tutte le modifiche del DOM nella vista successiva siano finite, causando un cambiamento di transizione. Quindi la mia domanda è; è possibile impedire che le classi ng-enter e ng-enter-active vengano aggiunte fino a quando non decido di aggiungerle (trasmettendo un evento da un controller o simile)?

Versione lunga

Sto sviluppando un'applicazione che utilizza AngularJS ui-router e ng-animate per le transizioni. Ho incontrato un piccolo problema di prestazioni, che mi piacerebbe davvero risolvere per rendere l'applicazione più scorrevole.

Le transizioni tra stati sembrano essere balbettanti, e ho scoperto che questo è probabilmente perché durante la transizione Angolare sta eseguendo cambiamenti DOM mentre la transizione è in corso.

Come posso assicurarmi che le modifiche al DOM nella vista successiva siano terminate prima di effettuare la transizione? Sto usando la funzione di risoluzione del router USB insieme a promesse che impediscono la transizione prima che i dati vengano caricati.

Ho creato un JSFiddle che illustra il mio problema. Quando si fa clic sul collegamento per inserire lo stato2, ci vuole un po 'prima che le righe di risoluzione vengano risolte con i dati (proprio come previsto). Tuttavia, non sembra che il DOM sia pronto quando la transizione ha luogo, poiché la transizione può essere abbastanza lenta. Questo mi fa pensare che il DOM non sia pronto quando la transizione ha luogo.

app.js

angular.module('myApp', ['ui.router', 'ngAnimate']) 
.config(['$stateProvider', 
    function ($stateProvider) { 
     $stateProvider 
      .state('state1', { 
       url: '', 
       views: { 
        'main': { 
         templateUrl: "state1.html", 
         controller: function(){ 

         } 
        } 
       } 
      }) 
      .state('state2', { 
       url: '/state2', 
       views: { 
        'main': { 
         templateUrl: "state2.html", 
         controller: function($scope, rows){ 
          $scope.rows = rows; 
         }, 
         resolve: { 
          rows: function($q){ 
           var rows = []; 
           var deferred = $q.defer(); 

           for (var i = 0; i < 10000; i++){ 
            rows.push({a: i, b: i/2, c: 3*i/2}); 
           } 

           deferred.resolve(rows); 

           return deferred.promise; 
          } 
         } 
        } 
       } 
      }); 
    }]) 

modelli

<div ui-view="main" class="main"></div> 

<script type="text/ng-template" id="state1.html"> 
    <a ui-sref="state2">Go to state 2</a> 
</script> 

<script type="text/ng-template" id="state2.html"> 
    <a ui-sref="state1">Back to state 1</a> 

    <table> 
     <tr> 
      <th>a</th> 
      <th>b</th> 
      <th>c</th> 
     </tr> 
     <tr ng-repeat="row in rows"> 
      <td>{{row.a}}</td> 
      <td>{{row.b}}</td> 
      <td>{{row.c}}</td> 
     </tr> 
    </table> 
</script> 

css

.main{ 
    transition: all 1s ease; 
    position: absolute; 
    width: 100%; 
} 

.main.ng-enter{ 
    transform: translateX(30%); 
    opacity: 0; 
} 

.main.ng-enter.ng-enter-active{ 
    transform: translateX(0); 
    opacity: 1; 
} 

.main.ng-leave{ 
    transform: translateX(0); 
    opacity: 1; 
} 

.main.ng-leave.ng-leave-active{ 
    transform: translateX(-30%); 
    opacity: 0; 
} 
+0

Hey Anton, puoi essere un po 'più specifico sui tuoi elementi e quando sta succedendo? Forse un codice sarebbe d'aiuto! – bobleujr

+0

Ciao @bobleujr! Ho aggiornato la mia domanda con entrambi i codici e un link a un JSFiddle! –

+0

Ho aggiornato nuovamente la domanda con una versione più breve del mio problema! –

risposta

2

La questione è ng-repeat . Crea un orologio per ogni elemento, così come il numero di elementi aumenta le prestazioni degrada. Più di 2000-3000 elementi avranno sicuramente un impatto sulle prestazioni di ng-repeat.

Se avete veramente bisogno di visualizzare gran numero di righe utilizzando ng-repeat, poi vorrei suggerire andare per:
1. impaginazione
2. scroll infinito utilizzando limitTo filtro.

Potete guardare qui per riferimento:
https://stackoverflow.com/a/17350875/5052704

Spero che questo aiuti !!

+1

La ng-repeat e il numero di elementi non è il problema principale. Non voglio che inizi la transizione prima che il DOM abbia finito con le modifiche. E non dovrebbe importare come viene creato il contenuto. Posso fare in modo che il mio controller trasmetta un evento o giù di lì ogni volta che il DOM è pronto, ma ho bisogno che nganimate non aggiunga la classe ng-enter-active prima di dire che dovrebbe farlo –

0

This è ciò che ho ottenuto dopo aver scartato problemi di github angolare. Sento che utilizzando feat ($ animate) si risolverebbe questo problema implicando un callback chiuso. Ti dispiacerebbe provarlo secondo il suggerimento nel link? Proverò a costruire il plunker con esso una volta che avrò un po 'di tempo in mezzo.

+1

Sembra che potrebbe essere qualcosa, devo guarda più in profondità! –