I am doing an Angular 2 demo with injection and get an error that my CustomDirective can't be used as an entry element.
So, my NgModule
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import AppComponent from './app.component';
import {NgModule} from "@angular/core";
@NgModule({
declarations: [AppComponent],
bootstrap:[AppComponent]
})
export class AppModule{}
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
AppComponent:
import {Component} from '@angular/core';
import {TIMER_DIRECTIVES} from './timer/timer';
import {TASK_DIRECTIVES} from './tasks/tasks';
import {SHARED_PROVIDERS} from './shared/shared';
@Component({
selector: 'tomato-app',
entryComponents: [TIMER_DIRECTIVES,TASK_DIRECTIVES],
providers: [SHARED_PROVIDERS],
template: `
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<strong class="navbar-brand">Tomato App</strong>
</div>
</div>
</nav>
<tomato-timer-widget></tomato-timer-widget>
<tomato-tasks></tomato-tasks>`
})
export default class AppComponent{}
And the custom directive itself:
import {Task} from '../shared/shared'
import {Input, HostListener, Directive} from '@angular/core';
@Directive({
selector: '[task]'
})
export default class TaskTooltipDirective {
private defaultTooltipText: string;
@Input() task: Task;
@Input() taskTooltip: any;
@HostListener('mouseover')
onMouseOver() {
if (!this.defaultTooltipText && this.taskTooltip) {
this.defaultTooltipText = this.taskTooltip.innerText;
}
this.taskTooltip.innerText = this.task.name;
}
@HostListener('mouseout')
onMouseOut() {
if (this.taskTooltip) {
this.taskTooltip.innerText = this.defaultTooltipText;
}
}
}
The problem is that I am using entryComponents in AppComponent incorrectly. How do I need to link a custom directive?
An entry component is any component that Angular loads imperatively, (which means you're not referencing it in the template), by type. You specify an entry component by bootstrapping it in an NgModule, or including it in a routing definition.
So when an Angular application is started, the main. ts file is loaded first, here we bootstrap the root module i.e. app.
A bootstrap component is automatically added to entryComponents. A list of components that can be dynamically loaded into the view.
entryComponents
: list of components that are dynamically inserted into the view of this component
How do I need to link a custom directive?
Put your all directive, pipe, component in declarations
array at NgModule
level:
@NgModule({
declarations: [AppComponent, TIMER_DIRECTIVES, TASK_DIRECTIVES],
bootstrap:[AppComponent]
})
export class AppModule{}
note that, if you declare provider
at Component
level:
@Component({
selector: 'tomato-app',
providers: [SHARED_PROVIDERS],
//...
})
it will create new instance for all instances of this component. in other word, if you have 2 different Component, with 2 declare providers: [SHARED_PROVIDERS]
, then the SHARED_PROVIDERS
of 2 component are different. you need declare in NgModule level to use same instance in all component of this NgModule.
@NgModule({
declarations: [AppComponent, TIMER_DIRECTIVES, TASK_DIRECTIVES],
providers: [SHARED_PROVIDERS],
entryComponents: [TIMER_DIRECTIVES, TASK_DIRECTIVES],
bootstrap:[AppComponent]
})
export class AppModule{}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With