Improve encapsulation be adding declarations array in @Component metadata
See original GitHub issueπ feature request
Relevant Package
This feature request is for @angular/coreDescription
Improve component encapsulation while removing cluttering of `NgModule`Describe the solution youβd like
Inside the `@Component` metadata, add the key: `declarations`, that key should accept an array of components, similar to the api used in `@NgModule`.@Component({
selector: 'nz-header',
template: `
<header>
<nz-nav></nz-nav>
</header>
`,
declarations: [NavComponent]
})
export class HeaderComponent { ... }
Describe alternatives youβve considered
Yes, Feature module and dynamic componentsLong description
One of the programming concepts that guides us as developers is encapsulation.
The ability to expose what we need to expose as public, and to hide the rest as private.
Consider the following components, module.
Our module AppModule
contains the following components:
HeaderComponent
NavComponent
FooterComponent
HeaderComponent
is placing the NavComponent
, and the NavComponent
will be used only in the HeaderComponent
The NavComponent
is a component that should only be used in the HeaderComponent
itβs like a private implementation of the HeaderComponent
.
Encapsulation rules should not expose NavComponent
to the other components inside our module.
So the FooterComponent
should not be able to place the NavComponent
since itβs private to the HeaderComponent
.
Currently to declare the structure above our AppModule
would look like this:
@NgModule({
declarations: [HeaderComponent, NavComponent, FooterComponent]
})
export class AppModule {}
this configuration will allow both the HeaderComponent
and the FooterComponent
to place the NavComponent
.
In my opinion this breaks encapsulation rules and clutters the NgModule
with a lot of components which should be private.
The ideal would be that we can declare the module like this:
@NgModule({
declarations: [HeaderComponent, FooterComponent]
})
export class AppModule {}
And declare the HeaderComponent
like this:
@Component({
selector: 'nz-header',
template: `
<header>
<nz-nav></nz-nav>
</header>
`,
declarations: [NavComponent]
})
export class HeaderComponent { ... }
And of course not allow the FooterComponent
to add the selector of the NavComponent
.
I can arrange a folder for the HeaderComponent
and arrange in that same folder all the private components that header is using.
The result will be:
- cleaner
NgModule
with smaller array of components - Better encapsulation in the components
- Better communication to the team regarding what components they can use and what is hidden
Issue Analytics
- State:
- Created 3 years ago
- Reactions:8
- Comments:9 (6 by maintainers)
This has definitely been discussed before, but I canβt find a duplicate issue. One of the goals of Ivy was to remove the need for NgModule. So it is definitely on the radar.
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.