我有一个Angular组件,它被用作超类(从来没有自己实例化过)。
因为有许多其他组件扩展了这个组件,并且每个组件操作不同类型的数据,所以超类使用一些泛型类型。
超类还需要能够实例化所提供类型的对象。因此,您可以看到组件的构造函数接受一个参数,该参数允许我为泛型类型定义构造函数。
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html'
})
export class MyComponent<Class1> implements OnInit {
public object!:Class1;
constructor(protected type1 : new () => Class1)
{
this.object = new this.type1();
}
}
注意,当子类组件调用super()时,它总是传递实际的类型(例如MyClass),所以组件有它可用。
非常重要:一切正常当我通过ng serve
运行时,泛型类型从子类组件传递,整个页面的功能,因为它应该。
我试图把这个通用组件变成一个库包,我可以在其他地方使用,但我发现,当我试图构建它,我得到这个错误:"错误NG2003:没有合适的注入令牌参数'type1'类'MyComponent'。">
Angular的编译器认为它应该向构造函数参数注入一些东西,尽管我将从不需要它这样做。
我怎样才能关闭它,这样编译器就会让我构建并传递构造函数参数,因为我已经知道我可以?
不要在父类上使用@Component
装饰器。在扩展这个类的实际组件上使用它。
或者为type
函数创建一个注入令牌,并从子类中提供它。
// export your typings and use them instead of any
export const TYPE_INJECTION_TOKEN = new InjectionToken<new () => any>(
'TYPE_INJECTION_TOKEN'
);
// shouldn't this be a directive ? Will you ever call it explicitly?
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html'
})
export class MyComponent {
public object;
constructor(_injector: Injector) {
const factory = _injector.get(TYPE_INJECTION_TOKEN);
this.object = new factory();
}
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [
{
provide: TYPE_INJECTION_TOKEN,
useValue: function () {}, // this is the constructor function
},
],
})
export class AppComponent extends MyComponent {
constructor(_injector: Injector) {
super(_injector);
}
}
我给上面的海报的检查,因为他的答案是正确的上下文提供的我的问题。然而,正如一些评论者指出的那样,在组件超类需要Angular特性(比如@ViewChild)的情况下,这并不是一个足够的答案。因为我确实使用Angular的特性,所以我找到了一个不同的解决方案:
constructor(@Inject(null) protected type1 : new () => Class1)
{
this.object = new this.type1();
}
显然,@Inject(null)
足以告诉Angular它不应该注入任何东西,编译器也不再抱怨了。