I'm working on upgrading my project from Angular 8 to 9, and I've come across a problem with new requirements when extending classes.
According to Angular's 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()
For @Component
decorators, it requires a template
or templateURL
on the base class. Adding either causes the child class to not render it's template.
For example, the following result in nothing rendering on the view:
@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);
}
}
I tried changing the base class to use templateUrl
pointing to an empty html, but that doesn't work either.
You have to add an empty @Directive()
decorator. As far as I know, that should be enough:
@Directive()
export abstract class BaseComponent<T extends AbstractSuperEntity> extends Toggler implements OnChanges {
@Input()
year: number | string
constructor(service: MyService) {
}
ngOnChanges() {
}
}
It's been quite a while after this question was asked, but I stumbled upon it so this might be useful to others as well.
You don't necessarily have to add the @Directive decorator. If it's a component just use @Component instead. That should work. See the following stackblitz example:
https://stackblitz.com/edit/angular-ivy-kehmwu?file=src/app/app.component.ts
In the question it's unclear what's wrong. An error message would help.
What also might've gone wrong is that the OP was not implementing the lifecycle method on the super call:
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();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.