2015-12-25 7 views
16

In Angular 2 gibt es irgendwelche spezifischen Fallstricke in Bezug auf Speicherverwaltung, sollte ich mir bewusst sein?Speicherlecks in Angular 2 verhindern?

Mit welchen Best Practices lässt sich der Zustand von Komponenten verwalten, um mögliche Lecks zu vermeiden?

Konkret habe ich einige Leute unsubscribing from HTTP observables in der ngOnDestroy Methode gesehen. Sollte ich das immer tun?

In Angular 1.X Ich weiß, dass wenn ein $scope zerstört wird, alle Zuhörer auf es auch automatisch zerstört werden. Was ist mit Observablen in Angular 2-Komponenten?

@Component({ 
    selector: 'library', 
    template: ` 
    <tr *ngFor="#book of books | async"> 
     <td>{{ book.title.text }}</td> 
     <td>{{ book.author.text }}</td> 
    </tr> 
    ` 
}) 
export class Library { 
    books: Observable<any>; 

    constructor(private backend: Backend) { 
     this.books = this.backend.get('/texts'); // <-- does it get destroyed 
               //  with the component? 
    } 
}; 
+0

nicht von beobachtbaren in ngOnDestroy –

+2

In Ihrem Fall abzubestellen den beobachtbare in 'ngOnDestroy' ist nicht notwendig, die' Async' Rohr austragen vergessen behandle all das für dich. Das wäre eine * gute Praxis *, statt der Zeichnung selbst das Rohr lässt für Sie, dass alles tun. –

+0

@EricMartinez, danke! Das würde ich als Antwort akzeptieren (vor allem wenn Sie einen Proof-Link angeben). – katspaugh

Antwort

13

Wie @katspaugh

In Ihrem speziellen Fall

angefordert gibt es keine Notwendigkeit manuell abmelden, da dies die Aufgabe des Rohr Async ist.

Überprüfen Sie die source code für AsyncPipe.

Der Kürze halber bin Entsendung ich den entsprechenden Code
class AsyncPipe implements PipeTransform, OnDestroy { 
    // ... 
    ngOnDestroy(): void { 
     if (isPresent(this._subscription)) { 
      this._dispose(); 
     } 
    } 

Wie Sie das Async Rohr sehen kann implementiert OnDestroy, und wenn es zerstört wird es überprüft, ob es gibt einige Abonnement und entfernt sie.

Sie würden das Rad in diesem speziellen Fall neu erfinden (Entschuldigung für die Wiederholung). Dies bedeutet nicht, dass Sie sich in einem anderen Fall, wie dem, auf den Sie verwiesen haben, nicht abmelden können/sollten. In diesem Fall übergibt der Benutzer das Observable zwischen den Komponenten, um sie zu kommunizieren, so dass es ratsam ist, sich manuell abzumelden.

Ich bin mir nicht bewusst, wenn der Rahmen automatisch alle lebendig Abonnements und abmelden von ihnen erkennen kann, wenn Komponenten zerstört werden, dass weitere Untersuchungen natürlich erfordern würde.

Ich hoffe, dies klärt etwas über Async-Rohr.

+0

Großartig, danke! – katspaugh

+0

Hey @katspaugh bekam ich eine Antwort von Rob und ich dachte, Sie daran interessiert sein könnte, überprüfen Sie es hier in dieser [Kommentar] (https://gitter.im/angular/angular?at=5681e8ce3c68940269251f9f) –

+1

Schauen Sie sich diese [Hangout Rede] (https://www.youtube.com/watch?v=UHI0AzD_WfY) als auch (min 27:40), ist es nicht zu diesem Thema geht tief, aber ich war wegen Ihrer Frage über sie neugierig und habe dieses Video herausgefunden. –

2

Sie müssen sich nicht von Standardabonnements abmelden, wie nach http.get(). Sie müssen sich jedoch vom Abonnement für Ihre benutzerdefinierten Themen abmelden. Wenn Sie eine Komponente haben und darin einen Betreff in Ihrem Dienst abonnieren, wird jedes Mal, wenn Sie diese Komponente anzeigen, ein neues Abonnement zum Betreff hinzugefügt.

Problems with my service

Bitte check this out: Good solution to make your components 'clean'

Mein persönlicher Ansatz - alle meine Komponenten aus dieser schönen Klasse erweitert werden:

import { OnDestroy, OnInit } from '@angular/core'; 
 
import { Subject } from 'rxjs/Subject'; 
 

 
/** 
 
* A component that cleans all subscriptions with oneself 
 
* https://stackoverflow.com/questions/38008334/angular-rxjs-when-should-i-unsubscribe-from-subscription 
 
* @class NeatComponent 
 
*/ 
 
export abstract class NeatComponent implements OnDestroy, OnInit { 
 
// Add '.takeUntil(this.ngUnsubscribe)' before every '.subscrybe(...)' 
 
// and this subscriptions will be cleaned up on component destroy. 
 

 
    protected ngUnsubscribe: Subject<any> = new Subject(); 
 

 
    public ngOnDestroy() { 
 
    this.ngUnsubscribe.next(); 
 
    this.ngUnsubscribe.complete(); 
 
    } 
 

 
    public ngOnInit(){} 
 
}

Und ich gerade hinzufügen super() Anruf zum Konstruktor und .akeUntil (this.ngUnsubscribe) vor jedem abonnieren:

import { NeatComponent } from '../../types/neat.component'; 
 

 
@Component({ 
 
    selector: 'category-selector', 
 
    templateUrl: './category-selector.component.pug' 
 
}) 
 
export class CategorySelectorComponent extends NeatComponent { 
 

 
    public constructor(
 
    private _shopService: ShopsService 
 
) { super(); } 
 

 
    public ngOnInit() { 
 
    this._shopService.categories.takeUntil(this.ngUnsubscribe) 
 
     .subscribe((categories: any) => { 
 
     // your code here 
 
     }) 
 
    } 
 
}