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

时间:2018-12-01 18:56:56

标签: angular typescript abstract-class angular-components angular-dependency-injection

抽象类:

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抽象类:

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

我的问题是,在load()组件的NewsPage实现中,注入的依赖项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();

}

1 个答案:

答案 0 :(得分:0)

构造函数应用于初始化类成员和进行依赖项注入。如果您需要初始化,则应使用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和更具体的构造函数。