Klasa abstrakcyjna:

export abstract class LanguageChangeAware {

    private sub: Subscription;
    protected language: string;

    protected constructor(protected eventService: EventService) {
        this.sub = eventService.getLang().subscribe(lang => {
            this.language = lang;
            this.load();
        });

        this.load();
    }

    protected ngOnDestroy(): void {
        this.sub.unsubscribe();
    }

    protected abstract load();
}

Komponent NewsPage implementuje LanguageChangeAware klasę abstrakcyjną:

export class NewsPage extends LanguageChangeAware {

    public news: Array<NewsItem>;

    constructor(public newsService: NewsService, protected eventService: EventService) {
        super(eventService);
    }

    protected load() {
        console.log('NewsPage - load() - ', this.newsService); // <- undefined

        this.newsService.getNewsItemsList().then(data => {
            this.news = data;
        });
    }
}

Mój problem polega na tym, że w implementacji load() składnika NewsPage wstrzyknięta zależność NewsService jest niezdefiniowana.


Jednym z możliwych rozwiązań, sugerowanym przez użytkownika Antoine Boisier-Michaud, było dokonanie subskrypcji wewnątrz metody ngOnInit.

Zaktualizowana wersja LanguageChangeAware:

export abstract class LanguageChangeAware implements OnInit, OnDestroy {

    private sub: Subscription;
    protected language: string;

    protected constructor(protected eventService: EventService) {
    }

    public ngOnInit(): void {
        this.sub = this.eventService.getLang().subscribe(lang => {
            this.language = lang;
            this.load();
        });

        this.load();
    }

    public ngOnDestroy(): void {
        this.sub.unsubscribe();
    }

    protected abstract load();

}
2
francosang 1 grudzień 2018, 21:56

1 odpowiedź

Najlepsza odpowiedź

Konstruktor powinien być używany do inicjowania elementów klasy i do wstrzykiwania zależności. Jeśli musisz wykonać czynności związane z inicjalizacją, powinieneś użyć metody ngOnInit. Po wywołaniu ngOnInit wiesz, że wszystkie zależności zostały rozwiązane.

export abstract class LanguageChangeAware implements OnInit {

    private sub: Subscription;
    protected language: string;

    constructor(protected eventService: EventService) { }

    protected ngOnInit(): void {
        this.sub = eventService.getLang().subscribe(lang => {
            this.language = lang;
            this.load();
        });

        this.load();
    }

    protected ngOnDestroy(): void {
        this.sub.unsubscribe();
    }

    protected abstract load();
}

Możesz przeczytać dokumentację Angulara na temat cykli życia, jeśli chcesz dowiedzieć się więcej o OnInit i innych hookach cyklu życia.

Możesz także przeczytać ten artykuł, w którym omówiono, kiedy używać OnInit i Konstruktor dokładniej.

1
Antoine Boisier-Michaud 16 luty 2021, 16:54