Starting an AngularJS project
I don't think there is any need to introduce AngularJS anymore, but here's a (very) small introduction of it to make sure everyone knows the basics.
AngularJS is a client-side framework, replacing the jquery code usually present on most sites. Instead of modifying the DOM on events manually (like displaying a div on a click event), AngularJS takes a declarative approach.
The following examples show the difference in paradigm between these two.
// jQuery version
$('my-button').click(function() {
$('my-div').show();
});
<!-- AngularJS version -->
<button ng-click="showDiv = !showDiv">Click me</button>
<div ng-show="showDiv">Hidden by default</div>
Some people will not like the fact that you're putting logic in the HTML, I personally much prefer this kind of approach to a jquery based one, and I find it much easier to organise your code using directives, controllers, services than the usual jquery spaghetti.
For a real overview, please check the official website.
Starting a new project🔗
A problem new developers encounter is how to organise their code. For simple (and I mean -learning how it works- kind of simple only), putting everything in one file is file but obviously does not work once you start working on bigger projects. Since I like organising code properly, I looked around to see what was the recommended way for that in AngularJS project.
ng-boilerplate by Josh David Miller🔗
While I didn't find THE answer (there's no imposed structure like in many server-side frameworks so everyone do their own thing, which can be great), I found ng-boilerplate by joshdmiller (link now dead). This boilerplate separates code by feature, containing all the code (including css/html) for that particular feature. It also uses ui-router which is quite awesome. It also comes with a whole lot of grunt tasks to automate dev/test/release cycle: everytime you save a file, it runs the associated task with this type of file and reloads your page. I used this boilerplate for a learning project, kCalculator and while it is a very good start, I found it not that practical for my own use (I use Sass, it uses LESS for example) and it had lots of things that I didn't really want.
My own ng-boilerplate🔗
Since I wanted to start a new project (which will be much more complex than kCalculator), I decided that this time I would use something tailored for me. Rather than forking and changing most of the code of the original, I started from scratch and added feature by feature what I needed. Result is ng-boilerplate (yes the name is lazy). The end results differs quite a bit from the original :
- no ng-min in the build (since you can do it by hand in your code)
- coffeescript only
- Sass with Foundation
- templates and css in their own directory instead of inside their small 'feature app'
- reorganised grunt tasks
- not concatenating dist libs with app libs (need to implement using CDN for dist libs on release task)
Architecture example🔗
Here is the layout of the project I'm working on (this is still very early, probably going to change some things later on) :
.
├── app
│  ├── app.coffee
│  ├── app.tests.coffee
│  ├── home
│  │  └── home.coffee
│  ├── teams
│  │  ├── list.coffee
│  │  ├── module.coffee
│  │  ├── service.coffee
│  │  └── tests
│  │  └── list.tests.coffee
│  └── users
│  ├── module.coffee
│  ├── new.coffee
│  └── service.coffee
├── assets
│  └── img
│  └── fonts
├── common
│  └── form
│  └── directives.coffee
├── index.html
├── style
│  ├── app.scss
│  ├── _forms.scss
│  ├── _normalize.scss
│  └── _settings.scss
└── templates
├── home
│  └── index.html
├── teams
│  └── list.html
└── users
├── main.html
├── new.html
└── verification.html
All of the different 'features' are nicely placed under the app folder and each file in it has a unique function. The module.coffee under each looks something like the following:
modules = [
'ui.router.state',
'users.new'
]
users = angular.module 'arena.users', modules
users.config ['$stateProvider', ($stateProvider) ->
$stateProvider.state 'users',
abstract: true
url: '/users'
views:
main:
template: '<ui-view/>'
$stateProvider.state 'users.new',
url: '/new'
templateUrl: 'users/new.html'
controller: 'NewUserCtrl'
data:
pageTitle: 'Register'
$stateProvider.state 'users.verification',
url: '/verification'
templateUrl: 'users/verification.html'
data:
pageTitle: 'Check your emails'
This file is the entry point of the feature, injecting all the different modules (list, create, etc) and defining the views (using ui-router). All of the other files are standard AngularJS controllers, services, directives. If I think something can be reused in another feature/project, it goes in the common directory.
Conclusion🔗
So far I really like this organisation, and this is working well for now. I will update it as the project grows bigger since I will probably find flaws by then.
How to learn AngularJS🔗
- egghead.io: short videos explaining very well everything
- thinkster.io: explains lots of concept using egghead videos as a base and expand on them