1.
Keep
your code organized
We need a directory structure that will make
it easy to
·
add
things as we go,
·
keep
the size of our modules manageable,
·
And
keep everything in an easy-to-navigate, logical structure.
2.
Use
ng-cloak to avoid FOUC (Flashes of un-styled contents)
When
your page first loads you will often see the angular code in the view before
Angular is loaded (especially on older browsers) – it will look something like
this (for a moment):
{{user}}
We have a
few options in order to get around this. One is to use ng-cloak – simply create
a style which says
[ng-cloak] {display:none; }
We usually
put this on the body tag, which means the page will only be shown once js is loaded. This also means there is a slight delay before anything is rendered.
3.
Including jQuery
Correct
way to include libraries like jQuery is before Angular JS because Angular comes with in-built
jQuery library called jqLite. If we define jQuery JS after Angular JS then
Angular first points to jqLite and then jQuery.
4.
Use
novalidate with form tag
This
will prevent the browser from submitting the form.
5.
Use
$timeout , not setTimeout
There
are some cases where one needs to perform some sort of timeout operation and we
frequently achieve this using JavaScript's setTimeout() function.
However,
if we use setTimeout() function in an AngularJS application we also need to use
$scope.apply() to ensure that any changes to the scope will be reflected
elsewhere (i.e. data-bound in a view).
AngularJS
provides a handy wrapper for this: $timeout - it does the $apply() call for us
so we don't have to.So using angular as our MVC front-end framework is you
should go all the way with angular and use its services instead of using native
functions like setTimeout() or console.log(), etc.
6.
Keep
controllers simple
Controllers
are meant to define your scope variables and encapsulate view related logic. Do
not use controllers for DOM interactions and manipulation. jQuery methods like
show/hide should not be used in controller, use ng-show/ng-hide instead. DOM manipulation should ideally be done in services and directives.
7. Only use
Events that are relevant globally across the entire app (such as a user authenticating or the app closing). If you want events specific to modules, services or widgets you should consider Services, Directive Controllers, or 3rd Party Libs.$broadcast()
, .$emit()
and .$on()
for atomic events
8.
Business
logic belongs to models
Data
processing should always be kept in models, that way they can easily be shared
between controllers and other services. Also, it’s easier to write unit test for
them.
9.
Use
services , not $rootScope to declare global
$rootScope
is a parent of all scopes so values exposed there will be visible in all templates
and controllers. Using the $rootScope is very easy as you can simply inject it
into any controller and change values in this scope. It might be convenient but
has all the problems of global variables.
Services
are singletons that you can inject to any controller and expose their values in
a controller's scope. Services, being singletons are still 'global' but you've
got far better control over where those are used and exposed.
10. Dos and don’ts:
a. $watch
i. DO use $watch in directives to update the DOM when a $scope
value changes.
ii. DON'T use $watch in a controller. It's hard to test and
completely unnecessary in almost every case. Use a method on the scope to
update the value(s) the watch was changing instead.
b.
$digest/$apply
i. DO use $digest/$apply in directives to let Angular know
you've made changes after an asynchronous call, such as a DOM event.
ii. DO use $digest/$apply in services to let Angular know some
asynchronous operation has returned, such as a Web Socket update, or an event
from a 3rd party library like Facebook API.
iii. DON'T use $digest/$apply in a controller. This will make
your code harder to test, and asynchronous operations outside of the Angular
framework don't belong in your controllers. They belong in services and
directives.
c. $routeParams
i. The $routeParams are only updated after a route change
completes successfully. This means that you cannot rely on $routeParams being
correct in route resolve functions. Instead DO use $route.current.params to
access the new route's parameters.