2016-06-09 16 views
9

ich mit ng-class einig seltsamen Problem habe, und ich bin zu ahnen, dass es mit Race-Bedingung zu tun hat.Race Condition mit ng-Klasse und Animation

Hier ist Plunker example

Hier ist der Code js relevant ist

self.slideLeft = function() { 
     if (self.end_index < self.list_of_stuff.length) { 
      self.direction = 'left'; 

      debugger; 
      self.start_index = self.start_index + 4; 
      self.end_index = self.end_index + 4; 
      self.display_list = self.list_of_stuff.slice(self.start_index, self.end_index);    
     } 

    } 

    self.slideRight = function() { 
     if (self.start_index > 0) { 
      self.direction = 'right'; 
      debugger; 

      self.start_index = self.start_index - 4; 
      self.end_index = self.end_index - 4; 
      self.display_list = self.list_of_stuff.slice(self.start_index, self.end_index);    
     } 
    } 

Hier ist der relevante html

<div class="stuff-wrapper"> 
    <div class="stuff" 
     ng-class="bCtrl.directionClass()" 
     ng-repeat="stuff in bCtrl.display_list"> 
     {{stuff}} 
    </div> 
    </div> 

Hier ist die Animation.

.left.ng-enter, 
.left.ng-leave { 
    -webkit-transition: all 1s ease-in-out; 

} 

.left.ng-enter { 
    transition-delay: 0.7s; 
    opacity: 0; 
    left: 10%; 
} 
.left.ng-enter-active { 
    opacity: 1; 
    left: 0; 
} 

.left.ng-leave { 
    opacity: 1; 
    left: -10%; 
} 
.left.ng-leave-active { 
    left: -20%; 
    opacity: 0; 
} 

Dies ist eine einfache App, die eine Liste von Nummer links und rechts schieben.

Wenn die linke Taste gedrückt wird, gleiten die Zahlen nach links.

Wenn die rechte Taste gedrückt wird, gleiten die Zahlen nach rechts.

Aber wir sehen, dass, wenn es zu einer Änderung der Richtung ist, wird die Zahl zuerst in der falschen Richtung verschoben werden, und die nachfolgende Richtung korrekt.

Ich vermutete, dass dies auf Race-Zustand zurückzuführen ist.

In der Tat sehe ich, dass ng-class wird nicht direkt nach dem Ändern der Richtung self.direction mit dem Debugger angewendet werden.

Dies ist sehr neugierig.

Gibt es eine Möglichkeit, dies zu bekämpfen?

Antwort

6

die Antwort von dieser (https://stackoverflow.com/a/21664152/2402929) Frage zitieren:

Sie müssen die Änderungen an den $ scope.elements nach dem CSS Klasse an dem DOM aktualisiert machen. Sie müssen also die DOM-Manipulation für eine Digest-Schleife verzögern. Dies kann durch die $ timeout Service durchgeführt werden (bitte sehen Sie diese Antwort für weitere Informationen AngularJS $ evalAsync vs $ timeout):

Ihre Elemente in der gleichen verdauen Schleife entfernt werden, wie Sie die CSS sind aktualisieren Klassen. Bedeutung - Die CSS wird nicht aktualisiert und die Elemente werden nur entfernt.

Die Digest-Schleife wird Ihre gesamte ng-Klick-Funktion umfasst, weil mit allen Winkeln Einbau-Richtlinien der Code in einem $ Umfang gewickelt ist. $ Anruf gilt.

Um zu klären.

$ scope $ apply() nimmt eine Funktion oder einen Winkel Ausdruck String und führt es aus, ruft dann $ scope $ Digest(), um alle Bindungen oder Beobachter zu aktualisieren. .

Hier können Sie mehr darüber lesen (http://jimhoskins.com/2012/12/17/angularjs-and-apply.html).

Also, was Ihr Problem löst die Verpackung ist das Entfernen von Daten aus dem Array in einen $ timeout Block, die die DOM-Manipulation für eine Digest-Schleife und trennen den Wechsel der Klassen und die Entfernung von Daten verzögern:

self.slideLeft = function() { 
      if (self.end_index < self.list_of_stuff.length) { 
       self.direction = 'left'; 

       self.start_index = self.start_index + 4; 
       self.end_index = self.end_index + 4; 
       $timeout(function(){ 
       self.display_list = self.list_of_stuff.slice(self.start_index, self.end_index);    
       }); 
      } 

     } 

     self.slideRight = function() { 
      if (self.start_index > 0) { 
       self.direction = 'right'; 

       self.start_index = self.start_index - 4; 
       self.end_index = self.end_index - 4; 
       $timeout(function(){ 
       self.display_list = self.list_of_stuff.slice(self.start_index, self.end_index);    
       }); 
      } 
     } 

Und hier ist ein Arbeits Plunker: http://plnkr.co/edit/30wJhL?p=preview

Verwandte Themen