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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With