befriending AngularJS

Over the past few weeks, I've explored Angular's architecture while building a Twitter replica, a tool for non-profit dashboards, and a to-do application. While it's relatively easy to get an app up and running, it's far more difficult to understand just how the MVVM architecture works - and how to optimize it for more complex apps. To that end, I've developed a workflow for beginning a basic Angular app.

My Workflow for Architecting Angular.js Applications

  1. I always start with the view (likely a .html file), and define the DOM elements that I want to be in scope for my Angular application. Angular is flexible in defining its own scope -- unlike Backbone, you can utilize Angular for only pieces of your application. Defining Angular's scope is as easy as inserting an ng-app directive into the relevant html tag. In the view, I also define a ng-controller, as well as any user inputs that I wish to translate into action.
  2. I then build controllers in .js files. In the controllers, I define the functions that will update the $scope object by calling services and factories. Note that controllers should not handle the model updating or logic themselves; this should be outsourced to the services and factories.
  3. Finally, I write the services and factories that return an object with defined properties and methods. The $scope object can then be updated by setting a $scope property to a property of the returned object.

Services and factories are extremely important in Angular. They should always be utilized (in lieu of the controller) for updating models. Models in Angular are essentially properties on the $scope object.

Factories in Angular return singletons, which are objects that are instantiated once at an application's runtime.

A basic implementation of a factory looks like this:

var app = angular.module('myapp', [ ]);

app.factory('myFactory', function ( ) {

     var factoryInstance = { };

     var factoryInstance.message = "";
     // some code that adds properties or methods to the factoryInstance
     factoryInstance.sayHello = function ( ) {
         factoryInstance.message = "Hello!";
     return factoryInstance;

Creating a factory returns an anonymous function that returns the 'factoryInstance' variable. One thing to remember here is that by default, using a factory to instantiate an object makes use of the functional instantiation pattern. You must create a new object and return it explicitly within the body of the factory.

A factory's methods are called in the controller:

app.controller('myController', function($scope) {  
    $scope.message = "";
     $scope.sayHello = function ( ) {
          factoryInstance.sayHello( );
          $scope.message = factoryInstance.message;     

The controller accesses the factoryInstance properties to update the $scope object, which acts as the model and passes along its information to the view.

<div ng-app= "myapp">  
    <div ng-controller= "myController">
         <h1> {{ message }} </h1>