Angular 抽象基础上的 9 个装饰器 class
Angular 9 decorators on abstract base class
我正在努力将我的项目从 Angular 8 升级到 9,并且在扩展 classes 时遇到了新要求的问题。
根据Angular的documentation:
Undecorated base classes using Angular features
As of version 9, it's deprecated to have an undecorated base class
that:
- uses Angular features
- is extended by a directive or component
Angular lifecycle hooks or any of the following Angular field
decorators are considered Angular features:
@Input()
@Output()
@HostBinding()
@HostListener()
@ViewChild()
/ @ViewChildren()
@ContentChild()
/ @ContentChildren()
对于 @Component
装饰器,它需要在基础 class 上使用 template
或 templateURL
。添加任何一个都会导致子 class 不呈现它的模板。
例如,以下结果不会在视图上呈现任何内容:
@Component({
template: ''
})
export abstract class BaseComponent<T extends AbstractSuperEntity> extends Toggler implements OnChanges {
@Input()
year: number | string
constructor(service: MyService) {
}
ngOnChanges() {
}
}
@Component({
templateUrl: 'my.component.html',
selector: 'my-component'
})
export class MyComponent extends BaseComponent<AbstractSuperEntity> {
constructor(service: MyService) {
super(service);
}
}
我尝试将基数 class 更改为使用指向空 html 的 templateUrl
,但这也不起作用。
您必须添加一个空的 @Directive()
装饰器。据我所知,这应该足够了:
@Directive()
export abstract class BaseComponent<T extends AbstractSuperEntity> extends Toggler implements OnChanges {
@Input()
year: number | string
constructor(service: MyService) {
}
ngOnChanges() {
}
}
问这个问题已经有一段时间了,但我偶然发现了它,所以这可能对其他人也有用。
您不一定要添加@Directive 装饰器。如果它是一个组件,只需使用 @Component 代替。那应该有效。请参阅以下 stackblitz 示例:
https://stackblitz.com/edit/angular-ivy-kehmwu?file=src/app/app.component.ts
问题中的问题不清楚。错误消息会有所帮助。
也可能出错的是 OP 没有在 super 调用上实现生命周期方法:
import { Component, OnInit, Input } from '@angular/core';
@Component({
template: '',
})
export abstract class BaseComponent implements OnInit {
@Input()
year: number | string;
constructor() {}
ngOnInit() {
console.log('This will only work if you call it in the child component');
}
}
@Component({
selector: 'child-component',
template: '<p>test, year: {{ year }}</p>',
})
export class ChildComponent extends BaseComponent implements OnInit {
constructor() {
super();
}
ngOnInit() {
super.ngOnInit();
}
}
我正在努力将我的项目从 Angular 8 升级到 9,并且在扩展 classes 时遇到了新要求的问题。
根据Angular的documentation:
Undecorated base classes using Angular features
As of version 9, it's deprecated to have an undecorated base class that:
- uses Angular features
- is extended by a directive or component
Angular lifecycle hooks or any of the following Angular field decorators are considered Angular features:
@Input()
@Output()
@HostBinding()
@HostListener()
@ViewChild()
/@ViewChildren()
@ContentChild()
/@ContentChildren()
对于 @Component
装饰器,它需要在基础 class 上使用 template
或 templateURL
。添加任何一个都会导致子 class 不呈现它的模板。
例如,以下结果不会在视图上呈现任何内容:
@Component({
template: ''
})
export abstract class BaseComponent<T extends AbstractSuperEntity> extends Toggler implements OnChanges {
@Input()
year: number | string
constructor(service: MyService) {
}
ngOnChanges() {
}
}
@Component({
templateUrl: 'my.component.html',
selector: 'my-component'
})
export class MyComponent extends BaseComponent<AbstractSuperEntity> {
constructor(service: MyService) {
super(service);
}
}
我尝试将基数 class 更改为使用指向空 html 的 templateUrl
,但这也不起作用。
您必须添加一个空的 @Directive()
装饰器。据我所知,这应该足够了:
@Directive()
export abstract class BaseComponent<T extends AbstractSuperEntity> extends Toggler implements OnChanges {
@Input()
year: number | string
constructor(service: MyService) {
}
ngOnChanges() {
}
}
问这个问题已经有一段时间了,但我偶然发现了它,所以这可能对其他人也有用。
您不一定要添加@Directive 装饰器。如果它是一个组件,只需使用 @Component 代替。那应该有效。请参阅以下 stackblitz 示例:
https://stackblitz.com/edit/angular-ivy-kehmwu?file=src/app/app.component.ts
问题中的问题不清楚。错误消息会有所帮助。
也可能出错的是 OP 没有在 super 调用上实现生命周期方法:
import { Component, OnInit, Input } from '@angular/core';
@Component({
template: '',
})
export abstract class BaseComponent implements OnInit {
@Input()
year: number | string;
constructor() {}
ngOnInit() {
console.log('This will only work if you call it in the child component');
}
}
@Component({
selector: 'child-component',
template: '<p>test, year: {{ year }}</p>',
})
export class ChildComponent extends BaseComponent implements OnInit {
constructor() {
super();
}
ngOnInit() {
super.ngOnInit();
}
}