Angular JS - Advanced Design Patterns and Best Practices

Keep your code organized


As developers we often struggle with code organization when scaling an application.
It gets messy and we start losing times searching for files.

 

The piles on the floor

AngularProject_JSFile_Structure.png

In this example from Angular-Seed project , objects of the same nature are regrouped into a single file. This demonstrate poor code organization and will lead to humongous files in no time. Another downside of this approach is losing useful insight provided by source control technologies like Git.
Inspired from this great article wrote by Cliff Meyers: Code Organization in Large AngularJS and JavaScript Applications

The socks drawer 

AngularJS_Folder_Structure_Directory.png

The next logical pass at organizing JavaScript involves creating a directory for some of the archetypes and splitting objects into their
own files. This is works better for small project but once you've reach more than 10 files per directory you start losing time again.
Drawers doesn't provide any insight about application architecture, we know that controllers are there but still need to dig to
understand their dependencies.

Modularity 

Modularity_In_AngularJS.png

With a modular organization is not just directory structure, it's architecture. Any random developer can now open the top-level folder and immediately gain insight into what the application does. Objects in the same folder now express their relationship and their dependencies to others.

 

Keep controllers simple


Controllers are meant to define your scope variables and encapsulate view related logic. Please don’t use controllers for
DOM interactions or data manipulation.
  
Angular is missing two critical things.
1. Structured class approach  & 2. class inheritance

Implement inheritance pattern using Class.js utility

Inheritance_Using_ClassJS.png

ClassUtility by John Resig ~ http://ejohn.org/blog/simple-javascript-inheritance/  

Keep your scope uncluttered

Scope_In_AngularJS.png

Angular dirty check each properties when it thinks some values changed. Every $digest or $apply will trigger this check. Carefully
selecting what is available on $scope and minimizing logic view bound functions is the key to build snappy applications.

Use Directives


Any DOM manipulation should take place inside a directive,

and only directives. Any code reusability should be encapsulated (behavioural and markup related) too.

DOM manipulation
DOM manipulation should be done inside the link method of a directive.

Bad:

Bad_DOM_Manipulation.png

Good:

Good_DOM_Manipulation.png

Communication between Directives
Custom directives can communicate with each other
● Directives are easy to create.
● Directives have their own scope
● Directives can communicate with the outside world via HTML attributes
● Directives encourage loose coupling
● Directives encourage reuse and UI consistency
● Directives are easy to test (well, this is a future article)
● Controllers can use directives with zero coupling

Index.html

Index_html.png

App.js

App_JS.png
App_JS.png
App_JS.png

Read the full article here: http://thesmithfam.org/blog/2012/12/17/communicating-between-directives-in-angularjs/

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. Plus it's easier to write unit test for them.

Sharing model with providers

Sharing_Model_With_Providers.png

It's also possible to write providers that returns a new instance of the model each time instead of sharing it.

Create facade to interact with servers 


Keep it simple, separate server interaction and error handling from the model.
That way model only handle data processing and code is easier to maintain

Sepearate_ServerInteraction_ErrorHandling.png

This can be injected in any model that needs to interact with slides RESTful API  

Leverage provider configuration


Angular gives developers the ability to configure providers before they are injected inside other objects in our application.
Use that to your advantage and handle global events like service errors from that level.

Configuring $httpProvider to intercept all requests

Configure_HttpProvider.png

Share a Notifications Service 


While it's a good solution to bridge gaps between directives, controllers and models we encourage you to use
$scope.$emit() and $scope.$broadcast when possible.
Don't overuse it.

How to use Notifications

Use_Of_Notifications.png

A basic notifications class is included in the source code here  

Automate your workflow 


AngularJS ecosystem is growing fast. Each month new tools are released.
Use them to build your own boilerplate and use that for your projects.

Yo_Tool_AnjularJS.png

Yo scaffolds out a new application, writing your Grunt configuration and pulling in relevant Grunt tasks that you might need for your build.

Grunt_Tool_AnjularJS.png

Grunt is used to build, preview and test
your project.

Bower_Tool_AnjularJS.png

Bower is used for dependency
management, so that you no longer have
to manually download and manage your
scripts.