2015-09-03 18 views
5

KurzversionStellen Sie sicher, DOM Änderungen abgeschlossen sind, bevor Übergang

Wenn ui-Router geht in eine neue Ansicht (mit ngAnimate in irgendeiner Weise, die ich nicht vollständig verstehen), ist es die Klassen fügt ng-leave und ng-leave-active zur aktuellen Ansicht. Außerdem werden die Klassen ng-enter und ng-enter-active zur nächsten Ansicht hinzugefügt. Das Problem besteht darin, dass der Übergang gestartet wird, bevor alle DOM-Änderungen in der nächsten Ansicht abgeschlossen sind, wodurch der Übergang abgehackt wird. Also meine Frage ist; Ist es möglich zu verhindern, dass die Klassen ng-enter und ng-enter-active hinzugefügt werden, bis ich beschließe, dass sie hinzugefügt werden sollen (durch Übertragung eines Ereignisses von einem Controller oder ähnlichem)?

Lange Version

ich eine AngularJS Anwendung entwickle, die für Übergänge ui-Router und ng-belebtes verwendet. Ich bin auf ein kleines Leistungsproblem gestoßen, das ich wirklich auflösen möchte, damit die Anwendung reibungsloser läuft.

Die Übergänge zwischen Zuständen scheinen zu stottern, und ich habe herausgefunden, dass dies wahrscheinlich ist, weil während des Übergangs Angular DOM-Änderungen durchführt, während der Übergang stattfindet.

Wie kann ich sicherstellen, dass das DOM Änderungen in der nächsten Ansicht abgeschlossen ist, bevor Sie den Übergang vornehmen? Ich verwende die Auflösungsfunktion von ui-router zusammen mit Zusagen, die verhindern, dass der Übergang stattfindet, bevor die Daten geladen werden.

Ich habe eine JSFiddle erstellt, die mein Problem veranschaulicht. Wenn Sie auf den Link klicken, um state2 einzugeben, dauert es eine Weile, bis die Auflösungszeilen mit den Daten aufgelöst werden (wie erwartet). Es scheint jedoch nicht so, dass das DOM bereit ist, wenn der Übergang stattfindet, da der Übergang ziemlich verzögert sein kann. Dies lässt mich denken, dass das DOM nicht bereit ist, wenn der Übergang stattfindet.

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; 
          } 
         } 
        } 
       } 
      }); 
    }]) 

Vorlagen

<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, können Sie ein wenig mehr spezifisch über Ihre Elemente sein, und wenn es passiert? Vielleicht würde ein Code helfen! – bobleujr

+0

Hallo @Bobleujr! Ich habe meine Frage mit Code und einem Link zu einem JSFiddle aktualisiert! –

+0

Ich habe die Frage erneut mit einer kürzeren Version meines Problems aktualisiert! –

Antwort

2

Die Frage ist ng-repeat . Es erstellt eine Überwachung für jedes Element, so dass die Anzahl der Elemente die Leistung verschlechtert. Mehr als 2000-3000 Elemente werden definitiv die Leistung von ng-repeat beeinträchtigen.

Wenn Sie wirklich große Anzahl von Zeilen mit ng-repeat müssen angezeigt werden, dann würde ich vorschlagen, gehen für:
1. Paginierung
2. endlosen Rolle mit limitTo Filter.

Sie können als Referenz hier:
https://stackoverflow.com/a/17350875/5052704

hoffe, das hilft !!

+1

Die ng-Wiederholung und die Anzahl der Elemente ist nicht das Hauptproblem. Ich möchte nicht, dass der Übergang beginnt, bevor das DOM mit den Änderungen fertig ist. Und es sollte egal sein, wie der Inhalt erstellt wird. Ich kann mein Controller Broadcast ein Ereignis oder so machen, wenn das DOM ist bereit, aber ich brauche, dass nganimate nicht die ng-enter-aktive Klasse hinzufügt, bevor ich sagen, dass es so –

0

This ist das, was ich bekam nach Winkel Github Probleme Verschrottung. Ich glaube, dass würde durch Verwendung von Leistung ($ belebten) dieses Problem beheben, indem sie voraus mit engen callback.Would Sie es gemäß dem Vorschlag in Verbindung versuchen, etwas dagegen? Ich werde versuchen, damit zu bauen, sobald ich etwas Zeit dazwischen habe.

+1

machen soll, wie es aussieht, könnte etwas, ich muss schau tiefer hinein! –

Verwandte Themen