I am upgrading my old AngularJS application to Angular using the NgUpgrade module. Upgrading components seems to work ok but I have struggled with getting a directive to work. After I couldnt upgrade my own component I copied the Highlight directive from the Angular tutorials and tried to use that instead.
So, I create the directive, add it to a directives module, then downgrade it for use within AngularJS.
When I do this I get an error:
Error: No component factory found for HighlightDirective. Did you add it to @NgModule.entryComponents?
Ok Mr compiler, no worries, I'll add it to the EntryComponents
. Refresh the page and...
Uncaught Error: HighlightDirective cannot be used as an entry component.
Now I am stumped, how do you make this work?
Highlight Directive
@Directive({
selector: '[highlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
Usage in HTML
<div highlight>
Directives.Module
@NgModule({
imports: [
CommonModule,
MiscDirectivesModule
],
entryComponents: [
DashboardBoxSmallComponent, // Components work fine, directives do not
HighlightDirective
],
declarations: [
DashboardBoxSmallComponent,
HighlightDirective
],
exports: [
HighlightDirective
]
})
export class DirectivesModule {
constructor() {
}
}
Directives.Module.AJS This is where my shiny Angular components are downgraded for AngularJS. The funky downgrade code is from here as apparently "Currently, you cannot downgrade attribute directives.".
const allowAttribute = directiveFactory => [
'$injector',
($injector: angular.auto.IInjectorService) =>
Object.assign($injector.invoke(directiveFactory), { restrict: 'EA' }),
];
const downgradeAttributeComponent = info => allowAttribute(downgradeComponent(info));
angular
.module("app.directives", [...])
.directive("highlight", downgradeAttributeComponent({ component: HighlightDirective }))
App.Module
@NgModule({
imports: [
BrowserModule,
UpgradeModule,
ServicesModule,
DirectivesModule, // This is the module shown above
FiltersModule
],
declarations: [],
entryComponents: [],
exports: []
})
export class AppModule {
constructor(private upgrade: UpgradeModule) {
}
ngDoBootstrap() {
this.upgrade.bootstrap(document.documentElement, [moduleName], { strictDi: true });
}
}