- Use the Angular UI Router over Angular's build in router. It provides child views, routing by state, and much more.
- Use the
resolve
property to resolve dependencies before control is handed to a controller and the page displays. This will reduce flickering during page transitions when retrieving data via REST calls needed for the view. Here is a very good tutorial and example - The current state is
$state.current.name
.
- Use Restangular. Restangular gives you a higher abstraction layer for your REST calls. With Restangular, you can add request and response interceptors, define a base api URL, handle errors, and much more.
- If you do not use Restangular, use
$resource
instead of$http
when possible. The higher level of abstraction will save you from redundancy.
- Use promises (
$q
) instead of callbacks. It will make your code look more elegant and clean, and save you from callback hell. - Get familiar with
$q.when()
and $q.reject(). It can save a lot of code. - Here's a great video from Dave Smith on promises.
- Use the Controller as syntax and as the first line of your controller add the line
var model = this
. This will place the controller object into $scope which you can use as your View Model. - On the occasions you need to add properties and functions to $scope, as a general rule of thumb, you should avoid direct bindings to the $scope's properties, but instead bind to an object bound the $scope. Per Google, this also reduces the risk around prototypal inheritance masking primitives. Here is an excellent video which explains this concept.
- Rather than
ngInit
to initialize values on a scope, initialize the values in the controller. The only appropriate use ofngInit
is for aliasing special properties ofngRepeat
.
- Broadcast and Emit are expensive so use them judiciously.
-
ng-if
vsng-show
: When you are conditionaly hiding/showing form field useng-if
instead ofng-show
. Becauseng-if
actually adds/removed the element from the DOM, the any validation on hidden fields will not fire.ng-show
, on the other hand, only hide DOM with css and therefore validations withinng-show
will be fired. The primary validation which will be affected is therequired
validation. If you use arequired
validation inside ang-show
, use theng-required
attribute with the same condition as being used by theng-show
and that will solve the issue also. -
One-time binding syntax: In Angular 1.3, use the one-time binding syntax
{{ ::value }}
where it makes sense// avoid <h1>{{ vm.title }}</h1> // recommended <h1>{{ ::vm.title }}</h1>
Why? : Binding once removes the watcher from the scope's
$$watchers
array after theundefined
variable becomes resolved, thus improving performance in each dirty-check -
Consider $scope.$digest: Use
$scope.$digest
over$scope.$apply
where it makes sense. Only child scopes will update$scope.$digest();
Why? :
$scope.$apply
will call$rootScope.$digest
, which causes the entire application$$watchers
to dirty-check again. Using$scope.$digest
will dirty check current and child scopes from the initiated$scope
- If you are using a JavaScript minifier (and you should), you must use
gulp-ng-annotate
orgrunt-ng-anotate
to add annotation dependencies. If this is not done, your app will not run after minification because Angular cannot tell what to inject.
Using Angular has it's gray areas in design decisions. One of these areas is when to use $rootscope. $rootScope is global, so it should be used carefully. (For web developers, think of how you use Session.)
Use $rootScope when you need to use an object globally throughout your whole app. Many folks believe that a Service should be used to store global objects and properties. I've tried this and it becomes too cumbersome to constantly inject the service into each controller which needs access to a global object or value. I generally create an object under $rootScope called SESSION. I then store all global values there.
Do not use $rootScope lazily. You do not want to litter $rootScope unnecessarily. Your first option should be to place the logic in a domain model if it is really needed globally.
- Make sure that all your buttons have
type='submit'
ortype='button'
. Some browsers will assume type is submit is no type is found. - Use
ng-submit
on your forms instead ofng-click
on the submit button
<form id="view_form" name="view_form" novalidate ng-submit="model.handleSubmit();">
...
<button type="submit">Next →</button>
</form>
- Angular apps do not depend on jQuery. Directives and other Angular features should solve all of your needs.
- The only real valid reason to include jQuery to use a jQuery plug-in which does not have an equivilent Angular directive. In these cases, you will need to include jQuery and optionally wrap the plug-in inside a directive with the help of something like the Angular UI jQuery Passthough directive. I know developers whom have had great success using this method.
- Use restful-ng-mock for mocking. It is a wraps Angulars ngMock and it a lot easier to use.
- Look at the AngularUI Bootstrap directives. Make sure you install using
bower install angular-bootstrap
instead ofbower install angular-ui-bootstrap
- Consider using Restangular which wraps and abstracts $http.
- Learn EM6 and TypeScript as soon as possible. You can down convert to EM5. This will prepare you for Angular 2.0.