Is it possable to declare one directive/component for many modules?
I can export only one:
import { Directive, ElementRef } from '#angular/core';
#Directive({ selector: '[appBigText]' })
export class BigTextDirective {
constructor(el: ElementRef) {
el.nativeElement.style.fontSize = '100px'
}
}
module one:
import { BigTextDirective } from '../common/directives/dir225';
#NgModule({
imports: [HttpModule...........
providers :[homeService],
declarations: [
HomeComponent,
DetailComponent,
BigTextDirective
]
component:
import { BigTextDirective } from '../common/directives/dir225';
#Component({
selector: 'my-app',
template: `
<router-outlet></router-outlet>
<div appBigText>This text is huge.</div>.
`
})
module two is same inculding, but i have error
Error:
Type BigTextDirective is part of the declarations of 2 modules: HomeModule and NotesModule! Please consider moving BigTextDirective to a higher module that imports HomeModule and NotesModule. You can also create a new NgModule that exports and includes BigTextDirective then import that NgModule in HomeModule and NotesModule.
In case you need using the same component/directive in multiple modules, it means that it's common. So why don't follow error suggestion and extract BigTextDirective to separate module and export it?
NgModule({
// ...
providers: [
BigTextTexture
]
exports: [
BigTextTexture
]
})
export class CommonModule {}
So you can easily re-use it in high-level modules just by importing it:
#NgModule({
imports: [
CommonModule
],
declaration: [
INeedBigTextTextureComponent
]
})
export class HighLevelModule {}
Let Angular helps you with code organization!
Related
I upgraded my app from Angular 11 to 12, and to typescript 4.2.4. When I do ng serve, app fails to compile with the error :
error NG6001: The class 'ChartComponent' is listed in the declarations of the NgModule 'PrototypeModule', but is not a directive, a component, or a pipe. Either remove it from the NgModule's declarations, or add an appropriate Angular decorator.
41 , ChartComponent
~~~~~~~~~~~~~~~~~~~~~~~~
src/app/chartPage/Chart/chart.component.ts:46:14
46 export class ChartComponent implements OnInit {
~~~~~~~~~~~~~~~~~~~~~~~~
'ChartComponent' is declared here.
This is the code in the PrototypeModule
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { ChartComponent } from './chartPage/Chart/chart.component';
#NgModule({
declarations: [
ChartComponent
]
schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
})
export class ChartPrototypeModule { }
#NgModule({
imports: [ChartPrototypeModule]
, exports: [],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class PrototypeModule { }
The ChartComponent is as follows :
import {Component, Input, ViewEncapsulation, Injectable, OnInit, SimpleChange, NgModule} from '#angular/core';
import { DataLoadService } from '../../services/data-load.service';
#Component({
selector: 'app-chart',
templateUrl: `./chart.component.html`,
styleUrls: ['./chart.component.scss']
, encapsulation: ViewEncapsulation.None
})
#Injectable({
providedIn: 'root'
})
#NgModule({
imports: [SharedModule]
})
export class ChartComponent implements OnInit {
constructor(private data: DataLoadService) {
//constructor code
};
}
I have no leads as to what might be causing the error. How do I fix this?
So, as #Muhammet Can TONBUL has mentioned you're using the component in a wrong way.
First of all your component should look something like this:
#Component({
selector: 'app-chart',
templateUrl: `./chart.component.html`,
styleUrls: ['./chart.component.scss'],
// Use this only if you DON'T want to encapsulate your SCSS
encapsulation: ViewEncapsulation.None
})
export class ChartComponent implements OnInit {
constructor(private data: DataLoadService) { ... };
...
}
The next step is to create a NgModule like you've already done:
#NgModule({
declarations: [
ChartComponent
],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
})
export class ChartPrototypeModule { }
So, now you've declared your component and you can use it now but currently only in the other components of the ChartPrototypeModule.
To change this, you need to export your component in the module as well. This would look something like this:
// Introduced an additional array so it is not needed
// to add your components twice
const COMPONENTS = [
ChartComponent
];
#NgModule({
declarations: [
COMPONENTS
],
exports: [
COMPONENTS
],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
})
export class ChartPrototypeModule { }
Now you can use your component in each module where you have imported the ChartPrototypeModule.
You can read more about feature modules here.
Note: If you're using the introduced array COMPONENTS to reduce redundancy only add the components to it, which you want to use outside of the module.
I had created a directive in my Core Module folder and added it to declarations and exported in such module. This module is implemented in App Module (The principal module). I use the directive decorator in my index page (This page is declared in another module Page Module) everything is well I don't receive any error but the logic of the directive is not triggering.
I have tried declaring the directive in the Page Module and its working. Also something very curious if remove the directive from the core module it throws the error Cannot determine the module for class HasfunctionalityDirective which is correct
Directive
import { Directive, ElementRef, Renderer2} from '#angular/core';
#Directive({
selector: '[appHasfunctionality]'
})
export class HasfunctionalityDirective{
constructor(
private elem: ElementRef,
private renderer: Renderer2
) {
this.renderer.setStyle(this.elem.nativeElement, 'color', 'blue');
}
}
Core Module
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { HasfunctionalityDirective } from './directives/hasfunctionality.directive';
#NgModule({
declarations: [
HasfunctionalityDirective
],
imports: [
CommonModule,
],
exports: [
HasfunctionalityDirective
]
})
export class CoreModule { }
App Module
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';
#NgModule({
declarations: [
AppComponent,
],
imports: [
CoreModule,
],
bootstrap: [AppComponent]
})
export class AppModule { }
Index.html
<p appHasfunctionality>
index works!
</p>
In this case the element 'p' should change the color to blue.
As you can see the app module receives all the elements of the core and angular doesn't throw any error but the logic is not triggering.
Found the solution to my problem, I was declaring the module on the top layer (main), instead of that I moved to the pages module because I realize this is the only place is used.
You can only get a refence to the element in afterviewinit. try this
import { Directive, ElementRef, Renderer2, AfterViewInit } from '#angular/core';
#Directive({
selector: '[appHasfunctionality]'
})
export class HasfunctionalityDirective implements AfterViewInit {
constructor(
private elem: ElementRef,
private renderer: Renderer2
) {
}
ngAfterViewInit() {
this.renderer.setStyle(this.elem.nativeElement, 'color', 'blue');
}
}
I've created a stackblitz where I'm trying to instantiate the HelloComponent dynamically using the ReflexiveInjector and I have the HelloComponent listed in the app modules entryComponents array.
However I'm still getting:
Component HelloComponent is not part of any NgModule or the module has not been imported into your module.
Thoughts?
Added a link to this SO in this feature request asking for virtual / logical modules. Please thumbs it up if you like the suggestion.
You should also declare the HelloComponent in your declarations array of your module. Read the official docs about entrycomponents.
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
#NgModule({
imports: [ BrowserModule, FormsModule ],
entryComponents: [HelloComponent],
declarations: [ AppComponent, HelloComponent ], // declare here
bootstrap: [ AppComponent ]
})
export class AppModule { }
I have been trying to create my own datatable, but facing issues.
So my app structure is like so:
where hkdt in my custom datatable module, I want to use this in my app module so that it is accessible everywhere.
hkdt.component.ts is:
import { Component } from '#angular/core';
#Component({
selector: 'hkdt',
exportAs: "hkdt",
templateUrl: './hkdt.html',
styleUrls: ['./hkdt.css']
})
export class HkdtComponent {
}
hkdt.module.ts is:
import { CommonModule } from "#angular/common";
import { NgModule } from "#angular/core";
import {HkdtComponent} from "./hkdt.component";
#NgModule({
imports: [CommonModule],
declarations: [HkdtComponent],
exports: [HkdtComponent]
})
export class HkdtModule {
}
index.ts is:
export * from './hkdt.component';
export * from './hkdt.module';
and I want to use it in my app.module.ts like so:
In my imports array of app.module.ts I import HkdtModule from import {HkdtModule} from "./core/hkdt";
and using it in some module like so:
<hkdt></hkdt>
below is my app.module.ts:
import {HkdtModule} from "./core/hkdt";
#NgModule({
declarations: [
AppComponent,
SignInComponent,
HomeComponent
],
imports: [
BrowserModule,
HttpClientModule,
FormsModule,
AppRoutingModule,
BrowserAnimationsModule,
HkdtModule
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule { }
but I get a console error:
Can anybody help me resolve me this problem.
Note: I do not want to import the component in the module and use it because I want to later publish my hkdt as a plugin and I want to make it work independently in a pluggable manner.
I can't figure out how to get directives working in my app. I want to apply a directive to a component, this is it in it's simplest form.
import {Directive, HostBinding} from '#angular/core';
#Directive({
selector: '[directiveSelector]'
})
export class FirstDirective {
#HostBinding() innerText = 'not working';
}
...
import {Component} from '#angular/core';
#Component({
selector: 'home',
template: `
<h1 directiveSelector>Test</h1>`
})
export class HomeComponent {
}
...
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { HomeModule } from "./home/home.module";
import { FirstDirective } from './directives/first.directive';
#NgModule({
imports: [
BrowserModule,
HomeModule
],
declarations: [
AppComponent,
FirstDirective
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Does anyone know what I am missing here? Home renders fine, and is a component wrapped in a module. Also, I cannot get a debugger or alert to fire off in the directive - may be a problem with the template binding?
Declare the FirstDirective in your HomeModule, that should take care of it. Here I assume that your HomeComponent is part of homemodule.
Tried leaving it out myself from a module, and it produced no error but also didn't work.