1

Ich erinnere mich daran, dass ich den Bereich für ein Element zerstören musste, bevor ich es aus dem DOM entfernte. Aber ich bin mir nicht sicher, wie das gemacht wird.Was muss ich vor dem Entfernen eines DOM-Elements in AngularJS tun?

So passiert es einfach, dass ich eine Direktive habe, die ein Element aus dem DOM entfernt. Eine abgespeckte Version würde wie folgt aussehen:

(function() { 
    angular.module('app').directive('remove', function() { 
     return { 
      restrict: 'A', 
      link: function(scope, element, attrs) { 
       element.children().remove(); 
       element.remove(); 
      } 
     } 
    }]); 
}()); 

Ein einfaches und unpraktisches Beispiel so etwas wie <my-directive-with-isolated-scope remove></my-directive-with-isolated-scope>

würde ich das Element entfernen kann, aber es scheint nicht, wie der Umfang zerstört wird, was ich Glauben würde ein Speicherleck richtig erstellen? Ich habe auch einen $interval im Controller der Direktive gesetzt (der mit dem isolierten Bereich), wo ich eine Konsolenmeldung gesetzt habe, um als Test auszugeben. Und ich kann sehen, dass es, wenn es aus dem DOM entfernt wird, immer noch eine Konsolennachricht im festgelegten Intervall abmeldet.

Würde ich etwas in der obigen Richtlinie ändern, um das Element richtig zu entfernen?

Antwort

0

Wenn das Element aus dem Bereich generiert wird, sollten Sie es zerstören, indem Sie die Bereichsdaten entfernen und es eckig neu rendern lassen, ohne eine DOM-Operation zu verwenden. Die Scope-Daten beziehen sich nicht auf das DOM-Element selbst, sondern auf das Element, das basierend auf dem Scope gerendert wird. Das Entfernen eines Elements hat also keine Auswirkung auf die Bereichsvariablen.

Sie sollten keine Richtlinie verwenden, um dies zu tun; Ändern oder entfernen Sie stattdessen den Wert aus dem Bereich.

1

Ein paar Experimente für Sie mit dem Element/scope Zerstörung versuchen:

Sie einen Test durchführen, um zu sehen, wenn der Umfang wie diese zerstört wird:

scope.$on('$destroy', function(){ 
    console.log('Scope Destroyed!'); 
}); 

Sie für das Element auch testen können sein zerstört:

element.on('$destroy', function(){ 
    console.log('Element Destroyed!'); 
}); 

(Bitte Events Abschnitt angular.element docs sehen)

Nun, über das Intervall:

Die $interval wird ausgeführt, bis Sie $interval.cancel() es, ob der Umfang oder nicht (es sei denn, der Rückruf existiert, ist eine Funktion zu scope in diesem Fall wird der Rückruf nicht definiert kann drehen gebunden und Ich bin mir nicht ganz sicher, wie $interval das handhabt).

Wenn Ihre Richtlinie ist eine $interval Funktion ausgeführt wird, haben Sie vielleicht so etwas wie:

var count = 0; 
var timer = 
    $interval(function doingStuff() { 
     console.log(count + ' seconds ...'); 
    }, 1000); 

scope.$on('$destroy', function cleanup() { 
    $interval.cancel(timer); 
}); 

Über benötigen manuell Bereiche zerstören:

Wenn Sie manuell einen Rahmen über var myScope = $scope.$new(); schaffen es liegt in Ihrer Verantwortung zerstöre es über myScope.$destroy();. Ich würde sagen, dass dies eine fortgeschrittene Verwendung ist und ich kann mir keine wirklich üblichen Gründe vorstellen, einen neuen Bereich manuell zu erstellen.

0

Richtlinien wie ng-view, ng-if, ng-repeat, ng-include usw. (Vielleicht, wenn Ihre Richtlinie ein Element und $compile es mit einem brandneuen Rahmen zu schaffen war), die Elemente auf das DOM hinzuzufügen, erstellen Sie zuerst ein Kind Umfang und Verwenden Sie den Dienst $compile, um diese Elemente mit diesem untergeordneten Bereich zu kompilieren und zu verknüpfen, bevor Sie sie an das DOM anhängen. Diese kompilierten Elemente sind mit dem erstellten untergeordneten Bereich verknüpft. Wenn diese Direktiven anschließend diese Elemente entfernen, zerstören sie auch den untergeordneten Bereich.

Um ein Kind Bereich zu erstellen:

var childScope = scope.$new(); 

das Kind Umfang zu zerstören:

childScope.$destroy(); 

Weitere Informationen finden Sie AngularJS rootScope.scope API Reference.

Verwandte Themen