@Component is a decorator. This means that it processes the class to which it is applied by adding some metadata data using the reflection metadata library. Angular2 does not look up metadata of parent classes. For this reason, decorators cannot be used in parent classes.
As for the BootstrapInputDirective directive, you can define it as a platform. This way, you will not need to include it every time in the directives attribute of your components.
Here is an example:
(...) import {PLATFORM_DIRECTIVES} from 'angular2/core'; bootstrap(AppComponent, [ provide(PLATFORM_DIRECTIVES, {useValue: [BootstrapInputDirective], multi:true}) ]);
Edit
Yes, you can create your own decorator to implement this. Here is an example:
export function CustomComponent(annotation: any) { return function (target: Function) { var parentTarget = annotation.parent; delete annotation.parent; var parentAnnotations = Reflect.getMetadata('annotations', parentTarget); var parentAnnotation = parentAnnotations[0]; Object.keys(parentAnnotation).forEach(key => { if (isPresent(parentAnnotation[key])) { annotation[key] = parentAnnotation[key]; } }); var metadata = new ComponentMetadata(annotation); Reflect.defineMetadata('annotations', [ metadata ], target); } }
The CustomComponent decorator will be used as follows:
@Component({ template: ` <div>Test</div> ` }) export class AbstractComponent { } @CustomComponent({ selector: 'sub', parent: AbstractComponent }) export class SubComponent extends AbstractComponent { }
Please note that we need to provide the parent class as a decorator contribution, since we can recognize this parent class in the decorator. Only the prototype of this class, but the metadata is applied to the class, and not to the associated prototype using reflection metadata.
Edit2
Thanks to Nitzam's answer, here is an improvement:
export function CustomComponent(annotation: any) { return function (target: Function) { var parentTarget = Object.getPrototypeOf(target.prototype).constructor; var parentAnnotations = Reflect.getMetadata('annotations', parentTarget); var parentAnnotation = parentAnnotations[0]; Object.keys(parentAnnotation).forEach(key => { if (isPresent(parentAnnotation[key])) { annotation[key] = parentAnnotation[key]; } }); var metadata = new ComponentMetadata(annotation); Reflect.defineMetadata('annotations', [ metadata ], target); } }
There is no need for a parent attribute to refer to a parent class in a custom decorator.
See this plunkr: https://plnkr.co/edit/ks1iK41sIBFlYDb4aTHG?p=preview .
See this question:
- How to get the parent class at runtime