Recently, I had to design an AngularJS application that would be highly modular. The idea was to let each module to create its own menu items and its own routes.
The final application should look like this:
The menu on the left should be generated on-the-fly, based on the requirements of individual modules.
It turned out it’s quite easy to do so using AngularJS provider
.
Wait a minute. What is AngularJS provider? Well, there is nice article in documentation.
For the sake of this article, provider is just a service, which is configured at application startup. And application startup is perfect time to build the menu. So let’s do it.
Core module
First of all let us create a module called app.core
. containing the Menu
service provider which holds application menu items:
Note the $get()
function. It is used by AngularJS at runtime to get an instance of Menu
service.
The add()
method can be called only at bootstrap (config
method) by other modules to add its own menu items.
And finally, MenuCtrl
is a controller which uses the menu service to get an instance of menu and render it.
Add modules
Let’s define another module and add a menu item:
Note that app.settings
module dependents on app.core
and during application bootstrap (config()
method) it adds menu item and respective routes.
Also note, that we are now dealing with MenuProvider
, not the Menu
service itself. We will use the service later in MenuCtrl.
Now let’s define another module with two more menu items:
Render menu
Menu rendering depends on the frontend framework you are using, so here is just a simple version for Twitter’s Bootstrap:
Of course you can add icons to achieve extra fanciness. Check this demo to learn about icons.
Putting it all together
Finally, we need to link all the individual modules into one root application and add a Home menu item. It’s basically just a list of submodule dependencies and default route handler:
The only issue in the example is that Home menu always appears on the last position because of module loading order. Fix it as your homework :)
Get the code above as a gist or see it in action.