2016-01-26 9 views
8

Heute hatte ich von diesem Code verursacht ein Leistungsproblem zu beheben: Achten Sie auf UpdateStats in der VorlageFunktion innerhalb einer Vorlage aufgerufen wird oft (Angular JS)

<script type="text/ng-template" id="entityGrouper"> 

<section> 

<div> 
<ul ng-click="hideEntityBox = !hideEntityBox"> 
<li> 
{{ entityNode.name }} 
</li> 
<li ng-repeat="breadcrumbItem in entityNode.breadcrumb"> 
{{ breadcrumbItem }} 
</li> 
</ul> 
{{ updateStats(entityNode) }} 
<span ng-include="'/mypath/views/resume.html'"></span> 
</div> 

<div> 

<div ng-repeat="entityNode in entityNode.group" ng-include="'entityGrouper'"></div> 
<div ng-repeat="entity in entityNode.group" ng-include="'entityBox'"></div> 

</section> 

</script> 

Template Verwendung genannt:

Nach dem Debuggen dieses Codes entdeckte ich, dass diese Funktion viel mehr Zeit als die Array-Größe aufgerufen wurde (mein Array hat 4 Objekte und die Funktion wurde mehr als 100 Mal aufgerufen), auch Maus Hover nannte diese Funktion. Ich habe das behoben, indem ich einfach ein ng-init in die Vorlage eingefügt habe und jetzt funktioniert es richtig, aber ich habe nicht herausgefunden, warum diese Funktion so oft aufgerufen wurde. Gibt es etwas über die Zwei-Wege-Datenbindung?

+0

Rufen Sie die gleiche Vorlage rekursiv auf? Es gibt wieder einen '

' Aufruf innerhalb der Vorlage – Developer

Antwort

1

Dies geschieht nicht, weil die Zweiwege-Datenbindung (es ist anwendbar Eingänge zu bilden), sondern wegen der Winkeländerungserfassungs. Angular überprüft regelmäßig, ob einer der Werte, die an eine Vorlage gebunden sind, geändert wurde, und wenn dies der Fall ist, wird der Wert in der Ansicht aktualisiert. In der Regel wird es durch benutzergenerierte Ereignisse ausgelöst. Um zu überprüfen, ob sich der Wert von updateStats(entityNode) geändert hat, wertet Angular es aus, was den Leistungseinbruch verursacht.

Um dies zu beheben, können Sie vorher genannten Einmal updateStats(entityNode)Bindung verwenden, wenn das Ergebnis einmal gesetzt ist und wird nie in der Zukunft ändern. Ich denke, das ist dein Fall, und du hast die Auswertung bereits auf ng-init verschoben. Für Werte, die mit der Zeit aktualisiert werden, wäre es besser, eine separate Eigenschaft in entityNode wie entityNode.stats zu erstellen, diese in der Vorlage anzuzeigen und die updateStats(entityNode) in Ihrem Controller oder Dienst nur bei Bedarf auszuführen. Dadurch verhindern Sie, dass auf jedem Digest-Zyklus updateStats(entityNode) ausgeführt wird (Sie haben bereits gesehen, wie oft dies der Fall ist) und verbessern dadurch die Leistung Ihrer App.

4

Es wird normalerweise empfohlen, ein $watch für solche Szenarien zu verwenden. Da Sie eine Funktion {{updateStats()}} binden, wird es bei jedem Digest-Zyklus ausgeführt.

Also in Ihrem Code, wenn ein Digest-Zyklus aufgerufen wird, wird es auch die Funktion aufrufen. Und Digest-Zyklen werden häufig intern in Angular genannt.

+0

Dies sollte die akzeptierte richtige Antwort sein – thiagoh

2

Was Sie sehen, ist das Ergebnis eines Digest-Zyklus.

Durch Hinzufügen einer :: wird die Funktion einmalige/einmalige Bindung aufgerufen.

{{ ::updateStats(entityNode) }}

+0

was :: genau tun? –

+1

'::' bietet einmalige Bindung an. Wenn Sie einem Ausdruck einen Präfix voranstellen, wird er nach dem ersten Digest nicht mehr ausgeführt oder neu berechnet. Weitere Informationen * Einmalige Bindung * Abschnitt der [Dokumentation] (https://docs.angularjs.org/guide/expression). –