You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Lazy loading components does not load FormModule/ngModel unable to bind #33654
But if i try and use any [(ngModel)] in the lazy loaded component, i get the following issue
Can't bind to 'ngModel' since it isn't a known property of 'select'
If i import the component in the app module it works as expected, but then its already pre loaded and does not lazy load
🔥 Exception or Error
ERROR in src/app/modules/contact-manager/contact-manager.component.html(12,9): error TS8002: Can't bind to 'ngModel' since it isn't a known property of 'select'.
changed the title [-]Lazy loading modules does not load FormModule[/-][+]Lazy loading components does not load FormModule/ngModel unable to bind[/+]on Nov 7, 2019
Please conside #34780 case as well, Where in this case we try to instantiate a component which using ngModel the #34780 is trying to bind it programatically.
declaring them in the NgModule means they are not lazy
Luckily, this isn't entirely accurate although I can most certainly see where the confusion comes from. Declaring a component in an NgModule does not necessarily mean they are not lazy. It all depends on how that NgModule is integrated in the full NgModule graph. Each NgModule can have imports and can be imported by other NgModules. The NgModules that are (transitively) imported from the root NgModule (typically AppModule) are not lazy loaded, but the NgModules that are not referenced in this way will not be loaded until you load them. This is typically done today using @angular/router using the loadChildren idiom, where you load the NgModule form within a dynamic import, allowing it to be lazily loaded as the Router is asked to load those children.
So to have a component that is supposed to be lazily loaded and use any declarations, you'd need an NgModule that declares the component and imports the necessary NgModules, but is not imported into any other NgModule. This allows the component to use the declarations that have become visible through the NgModule.
The tricky bit is what to do with that extra NgModule. In some situations, you could only lazily load the component without loading the NgModule that declares it, provided that you're using AOT compilations. During AOT compilation, the compiled component will have explicit references to the declarations that it actually uses, so the NgModule is not strictly necessary for the component to render. However, it could be that the NgModule is also used to provide additional providers for DI that were not already loaded into an Injector from AppModule. In that case, the NgModule must also be lazily loaded and instantiated to obtain its Injector which contains the registered providers. This is exactly how the Router operates, by the way.
The confusing part is how NgModules serve two purposes: declaration scopes and DI provider registration. In AOT compilations the scope information is not really needed, but the DI information may certainly be. Unfortunately it's almost impossible to know if a certain NgModule and the NgModules that it imports do register providers for DI purposes, so it's always guessing whether a component can be lazily imported without needing to load its NgModule as well.
Thank you for the excellent explanation, I think I understand that, however it doesn't help me understand how to do what I need to do, or if what I'm trying to do will be possible.
Yes, so I can not do what I want too, I think lazy loading components is pretty much a a requirement for app optimisation, I was excited at angular connect when this was demo'ed. could you explain a way to lazy load a component and even if its maybe a future feature, or be able to assign the declarations in the component and outside of the module ?
@neofuture Is it still the problem that if you lazy-load only a component, it's not able to load also all types of dependencies except providers because only them you are able to declare on that component level? If there are other parts, like pipes, other modules and so, you have to lazy-load a module and not that component itself?
Have the same issue on CLI 9.0.2
` ERROR in src/app/configurations/openings/edit-opening/edit-opening.component.html:3:64 - error NG8004: No pipe found with name 'async'.
3 <h4 class="modal-title" id="modal-title">{{ SelectedDate | async }}</h4>
~~~~~~
src/app/configurations/openings/edit-opening/edit-opening.component.ts:7:18
7 templateUrl: './edit-opening.component.html',
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component EditOpeningComponent.`
@NgModule({
declarations: [EditOpeningComponent],
imports: [CommonModule]
})
class EditOpeningModule {
}
Try adding this lines in the end of the edit-opening.component.ts @maxstee
@neofuture Why don't you use this approach? There's a clear explanation of why you can't use plain component (without declaring in module) as lazy loaded component by @JoostK, but as I see and as you really want to use it without of declaring it in any other modules just give the component its own module.
Also you can support my issue here if you think this will be a good approach of doing what you want to do.
@JoostK you are a star thank you for giving me the solution, the forms work fine now, understanding is a great thing
It seems having a module declaration in the component that handles the declarations allow you to have the module definitions too, as you factory those in too, I probably didn't explain that right but I get the pattern now
@levani132 awesome thank you I didn't read that until I went away and did what I did, but that's pretty much my solution, thank you for your comments and advice, what an awesome community 👍
Activity
[-]Lazy loading modules does not load FormModule[/-][+]Lazy loading components does not load FormModule/ngModel unable to bind[/+]neofuture commentedon Dec 3, 2019
Does anyone know a work around for this issue ?
neofuture commentedon Dec 13, 2019
Since updating to rc6 this is now now returned as an error but now as a warning
Can't bind to 'ngModel' since it isn't a known property of 'select'.
neofuture commentedon Dec 13, 2019
I have created a repo to illustrate the issue
https://github.com/neofuture/lazyload
fkolar commentedon Jan 15, 2020
Please conside #34780 case as well, Where in this case we try to instantiate a component which using ngModel the #34780 is trying to bind it programatically.
18 remaining items
JoostK commentedon Jul 24, 2020
@neofuture Let me try to go over it:
Luckily, this isn't entirely accurate although I can most certainly see where the confusion comes from. Declaring a component in an NgModule does not necessarily mean they are not lazy. It all depends on how that NgModule is integrated in the full NgModule graph. Each NgModule can have imports and can be imported by other NgModules. The NgModules that are (transitively) imported from the root NgModule (typically
AppModule) are not lazy loaded, but the NgModules that are not referenced in this way will not be loaded until you load them. This is typically done today using@angular/routerusing theloadChildrenidiom, where you load the NgModule form within a dynamic import, allowing it to be lazily loaded as the Router is asked to load those children.So to have a component that is supposed to be lazily loaded and use any declarations, you'd need an NgModule that declares the component and imports the necessary NgModules, but is not imported into any other NgModule. This allows the component to use the declarations that have become visible through the NgModule.
The tricky bit is what to do with that extra NgModule. In some situations, you could only lazily load the component without loading the NgModule that declares it, provided that you're using AOT compilations. During AOT compilation, the compiled component will have explicit references to the declarations that it actually uses, so the NgModule is not strictly necessary for the component to render. However, it could be that the NgModule is also used to provide additional providers for DI that were not already loaded into an
InjectorfromAppModule. In that case, the NgModule must also be lazily loaded and instantiated to obtain itsInjectorwhich contains the registered providers. This is exactly how the Router operates, by the way.The confusing part is how NgModules serve two purposes: declaration scopes and DI provider registration. In AOT compilations the scope information is not really needed, but the DI information may certainly be. Unfortunately it's almost impossible to know if a certain NgModule and the NgModules that it imports do register providers for DI purposes, so it's always guessing whether a component can be lazily imported without needing to load its NgModule as well.
More information can be found here: #35759 (comment)
neofuture commentedon Jul 24, 2020
Thank you for the excellent explanation, I think I understand that, however it doesn't help me understand how to do what I need to do, or if what I'm trying to do will be possible.
neofuture commentedon Jul 25, 2020
Yes, so I can not do what I want too, I think lazy loading components is pretty much a a requirement for app optimisation, I was excited at angular connect when this was demo'ed. could you explain a way to lazy load a component and even if its maybe a future feature, or be able to assign the declarations in the component and outside of the module ?
mlc-mlapis commentedon Jul 25, 2020
@neofuture Is it still the problem that if you lazy-load only a component, it's not able to load also all types of dependencies except providers because only them you are able to declare on that component level? If there are other parts, like pipes, other modules and so, you have to lazy-load a module and not that component itself?
levani132 commentedon Jul 25, 2020
@neofuture Why don't you use this approach? There's a clear explanation of why you can't use plain component (without declaring in module) as lazy loaded component by @JoostK, but as I see and as you really want to use it without of declaring it in any other modules just give the component its own module.
Also you can support my issue here if you think this will be a good approach of doing what you want to do.
neofuture commentedon Jul 25, 2020
WOW
It is possible
Template
Component
Lazy loading
@JoostK you are a star thank you for giving me the solution, the forms work fine now, understanding is a great thing
It seems having a module declaration in the component that handles the declarations allow you to have the module definitions too, as you factory those in too, I probably didn't explain that right but I get the pattern now
neofuture commentedon Jul 25, 2020
@levani132 awesome thank you I didn't read that until I went away and did what I did, but that's pretty much my solution, thank you for your comments and advice, what an awesome community 👍
neofuture commentedon Jul 25, 2020
also thanks to @mlc-mlapis you are absolutely correct... thank you
neofuture commentedon Jul 29, 2020
This is possible and is not a bug, with the kind explanations, there is a way to do this so this should be closed now
angular-automatic-lock-bot commentedon Aug 29, 2020
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.