网站搜索

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


抽象类:

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

我的问题是,在 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();

}

答案#1

构造函数应用于初始化类成员和依赖注入。如果你有需要进行的初始化操作,你应该使用 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 的生命周期文档。

你也可以阅读这篇文章,它更具体地讨论了何时使用 OnInit 和构造函数。