组件中的抽象方法实现具有未定义的依赖关系

Abstract method implementation in component has undefined dependencies

摘要class:

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();
}

组件 NewsPage 实现 LanguageChangeAware 抽象 class:

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;
        });
    }
}

我的问题是,在 NewsPage 组件的 load() 实现中,注入的依赖项 NewsService 未定义。


用户 Antoine Boisier-Michaud 建议的一种可能的解决方案是在 ngOnInit 方法内进行订阅。

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();

}

构造函数应该用于初始化 class 成员和依赖注入。如果您有需要做的初始化工作,您应该使用 ngOnInit 方法。当调用 ngOnInit 时,您知道所有依赖项都已解决。

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();
}

如果您想了解有关 OnInit 和其他生命周期挂钩的更多信息,可以阅读 angular's documentation on lifecycles

您还可以阅读 this article,其中更具体地讨论了何时使用 OnInit 和构造函数。