Angular 9中的BaseComponent与@Injectable()

14
在Angular 8中,我能够创建带有“@Injectable”属性的基础组件(即实际组件继承的类)。但是在Angular 9编译器中,我收到以下信息告诉我:

YourComponent 组件继承了 BaseComponent 的构造函数,但后者没有自己的 Angular 装饰器。依赖注入将无法解析 BaseComponent 构造函数的参数。要么在 BaseComponent 上添加 @Directive 装饰器,要么在 RoleSelectDialogComponent 中添加显式构造函数。

现在应该如何在Angular 9中进行这些操作?虽然这种做法可行,但看起来有点 hacky:

```html
```
@Component({
    selector: 'baseComponent',
    template: 'no-ui'
})

你能分享一下你的两个组件吗?看起来你没有使用基础构造函数,请分享更多代码。 - Ali Adravi
"YourComponent" 在 Angular9 中没有任何构造函数。 - tris
BaseComponent怎么样?如果你想得到正确的答案,一定要更详细地解释你的问题并分享代码。 - Ali Adravi
6个回答

14

提示在消息中

将@Directive装饰器添加到BaseComponent中

给它添加一个@Directive()应该可以解决问题。

我正在进行升级,我的基础组件自动添加了@Directive()装饰器。


这是最佳实践吗?我的 BasComponent 真的不算是“指令”吧? - tris
在 Angular 中的错误信息中建议这样做,所以我会这么说。 - Kurt Hamilton
似乎是正确的答案:https://github.com/angular/angular/issues/35367#issuecomment-585136872 - tris
这个方法可以解决问题,但是现在TSLint存在一个问题。被装饰为指令的类应该以后缀“Directive”结尾。因此,这个解决方案看起来像是一个变通方法。 - Nickon

12

随着 Angular 10 的发布,警告现在已成为错误,这将影响更多人。

错误 NG2007:类正在使用 Angular 功能,但未被装饰。 请添加显式的 Angular 装饰器。

本博客文章展示了一些例子:https://volosoft.com/blog/what-is-new-in-angular-10


此外,请注意,“Angular 功能”不仅指依赖注入。即使你在基类中存在 ngOnDestroy(),也会触发此错误。

我通过将 ngOnDestroy() 重命名为 _ngOnDestroy() 并在实际 @Injectable() 销毁时从子类中调用它来解决了此问题。如果我将来再次进行子类化并忘记调用 _ngOnDestroy(),这似乎有点危险,但我不确定是否有更好的选择。


你今天找到任何替代方案了吗? - Logan Wlv
很抱歉,@LoganWlv,没有。只有在几个地方有它。 - Simon_Weaver

1

0

确保导出基类

又遇到这个问题了!这一次,我试图通过故意不导出基类来变得聪明起来。

@Directive()
abstract class _SnippetDirective<P>

Angular说不行!

指令SnippetDirective继承其构造函数自_SnippetDirective,但后者没有自己的Angular装饰器。依赖注入将无法解析_SnippetDirective构造函数的参数。要么为_SnippetDirective添加@Directive装饰器,要么为SnippetDirective添加显式构造函数。

但当然它确实有一个指令。我想正在发生的是它甚至不认识基类作为指令,因为它没有对它的可见性。这只是一个猜测,但从逻辑上讲是有道理的。

导出基类就可以解决问题。还有删除“abstract”关键字。


0
你需要在基类中添加一个装饰器(@Directive),或者移除基类实现的任何Angular接口。这个错误是在我将一个应用程序升级到Angular 10之后开始出现的。一个抽象的基类正在实现Angular的OnInit接口。这个类后来被实际的组件类扩展。我没有添加无关的装饰器,而是从基类中移除了OnInit的实现,这样就解决了错误。

0

正如@Simon_Weaver所说,您可能有一个父类,例如:

export class BaseComponent implements OnDestroy {
  protected subscriptions: Subscription[] = [];

  ngOnDestroy(): void {
    this.subscriptions.filter(sub => !!sub).forEach(subscription => {
      subscription.unsubscribe();
    });
  }
}

不必为每个子组件添加ngOnDestroy,你可以这样做:

/* tslint:disable */
@Directive()
export class BaseComponent implements OnDestroy {
  protected subscriptions: Subscription[] = [];

  ngOnDestroy(): void {
    this.subscriptions.filter(sub => !!sub).forEach(subscription => {
      subscription.unsubscribe();
    });
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接