Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular.js organize controllers into App namespace

I'm starting to use Angular.js on a new project and from the basic tutorials, I see mostly a single controllers.js file that contains all the controller functions, each which are bound to the window object.

It seems that a better practice would be use the existing "myApp" namespace, to add controllers to, for example:

myApp.controllers = {}; myApp.controllers.userItem = function($scope) {} 

All controllers would be part of the created "myApp.controllers" object or "window.myApp.controllers".

Does anyone suggest a better or more organized way to handle controllers or other item, custom services, directives, etc. would use the same structure.

In addition to this, I'm debating about putting each controller into it's own file, which ultimately would be combined for production, but depending on the size of the app, it may be a bit overkill and only cause more work bouncing around between files.

Any suggestions would be greatly appreciated.

Thanks!

like image 914
dzm Avatar asked Jan 30 '13 05:01

dzm


1 Answers

Great question!

I don't like that the tutorials and documentation take a "package-by-layers" approach to their code. I think that is probably done for convenience in teaching concepts, which is great, but that approach has limited applicability in the real world.

Package-by-feature is a far better approach:

|- README |- src/    |- app/       |- app.js       |- feature1/       |- feature2/       |- ...    |- vendor/       |- angular/       |- bootstrap/       |- ...    |- assets/    |- less/    |- index.html 

Inside src/app, you can package your contents based on the section of the site you're working on (e.g. menus) and by routes (e.g. product list and product detail). Each can be declared like so:

angular.module( 'products', [   'productCatalog',   ... ]) 

And each module can have its own routes:

.config( [ '$routeProvider', function( $routeProvider ) {   $routeProvider.when( '/products', { ... } );   $routeProvider.when( '/products/:id', { ... } ); }); 

And controllers, etc:

.controller( 'ProductListCtrl', [ '$scope', function ( $scope ) { ... } ]); 

So everything that goes together is packaged in the same directory. And you can place all of your components in separate files, with one module per file (if you wish; I usually do). And in your top-level app, you simply declare your dependencies:

angular.module( 'app', [   'products',   ... ]); 

You can also bundle general-purpose directives by themselves, too, to keep your tests and documentation all together - again, by feature! And each of these components are drag-and-drop reusable in future projects.

A great reference implementation is angular-app. Check it out!

Update: Since this answer, I started an AngularJS project kickstarter/template called ngBoilerplate to encapsulate these concepts (among many other best practices) and a sophisticated build system to support them.

like image 169
Josh David Miller Avatar answered Sep 24 '22 11:09

Josh David Miller