I was refactoring my project to match the Angular2 styleguide at https://angular.io/guide/styleguide At first I had one module so there was no problem. Now while refactoring and with splitting into modules I got circular dependencies because of the navigation between pages of different modules.
Simplified, I have three modules, each having components:
Shared
BookListItemComponent
AjaxSpinnerComponent
FormHelperComponent
…
Books
BookComponent
Shops
ShopListComponent
Modules Books and Shops each import Shared. The BookListItemComponent shows a book title, and when tapped navigates to the BookComponent which show the book’s details.
The ShopListComponent shows a list of books of a certain shop.
Since the Books module imports the Shared module to use the spinner etc. this creates a circular dependency. How are we supposed to solve this?
In an app you navigate between pages of different modules. I don’t see a way to avoid having these pointing at each other. Especially with the BookListItemComponent which is used all over the app to list books.
I have pages like:
Top100 of books
List of publishers of which the detail page shows a list of books
Book shops listing books
Profile page of user with list of their books
etc.
If I need to merge all components navigating to a book I end up in having one single app module again.
Hey man, I just posted an answer to your SO question. I feel your pain because we went through the same struggle at work. if my SO answer doesn’t answer your question, please feel free to message me here. I’d be happy to help because I know this is a tough issue. But organizing your code to match Angular guidelines is so worth it
I don’t think components should be interacting with the navigation system, only pages. That might make the circular dependency problem go away naturally.
Imagine to have for example an avatar, when tapped opens the user profile. Then you have to handle the navigation everywhere you use this avatar component. So if you decide to change the target page you have to change all the pages using the avatar component.
As a user, I would find it confusing if tapping on an avatar component changed the active page. Having it throw up a popover with user information I could see, but not actually modifying the nav stack. Maybe that’s just me, though.
I noticed another scenario where the dependencies are a problem. I have multiple services for different tasks. These services do something and change observables. A lot of modules subscribe to these observables. This makes the services automatically need to go into the shared module.
This sounds dangerous. Pages aren’t destroyed until they are popped off the nav stack (or if you do it programmatically). The setup you describe is an outof-memory error waiting to happen, if the user is allowed to click avatar after avatar to explore the userbase.
I try to create a navigation tree that is shallow depth – maybe several start points, but no starting view can have more than say 5 pages on top of it. Base pages and modals on top of the base pages, so the user must return to the base eventually. If you want a feel like the Ionic forum, so to speak, you need to reset the root on a regular basis, so your memory of the past is capped.
Regarding components and modules, I make pages smart containers and components dumb containers. That isn’t the only way to design, but it fits well with Angular change detection, and it avoids circular dependencies.
The book app was an example to simplify my question. The real app is about whisky. Out of curiosity I’ve tested the app to trigger a memory leak and navigated about 30 times from whisky -> brand -> distillery -> ind. bottlings -> whisky -> distillery etc. worked fine without memory issues on an old Android phone.
To give you a better impression about the navigation, I drew a navigation schema below. I do not really see a solution to eliminate navigation loops. If I make whisky the endpoint for all navigation the user misses the exploration of the whisky properties like the distillery etc.