Real World Apps

Files & Folders

Module Organization

Naming Objects

Organizing Your Project

Files & Folders

app/               
  css/              
    app.css         
  img/              
  index.html       
  index-async.html 
  js/              
    app.js         
    controllers.js 
    directives.js  
    filters.js     
    services.js    
  lib/             
    angular/
      angular.js   
      angular.min.js
      angular-*.js  
      version.txt   
  partials/         
    partial1.html
    partial2.html

test/               
  e2e/              
    runner.html     
    scenarios.js    

  unit/             
    controllersSpec.js
    directivessSpec.js
    filtersSpec.js    
    servicesSpec.js   

Directory layout by

  • Just one file for each type of object.
  • Each file contains all objects of that type.
  • Not real applications (tutorials, demos, hello-worlds).
  • Not recommended at all.

angular-seed

Files & Folders

app/               
  css/              
    app.css         
  img/              
  index.html       
  js/              
    app.js
    controllers         
        controller1.js 
        controller2.js 
    directives
        directive1.js  
        directive1.js 
    filters
        filter1.js
        filter2.js
    services
        service1.js
        service2.js 
  partials/         
    partial1.html
    partial2.html

  lib/             
    angular/
      angular.js   
      angular.min.js
test/               
  e2e/              
    runner.html     
    scenarios.js   
  unit/             
    controllersSpec.js
    directivessSpec.js
    filtersSpec.js    
    servicesSpec.js   

Directory layout

  • Files of the same object type are organized into a single folder.
  • Hard to find a file if there are more than 10 in a sub-folder.
  • Related files of a module are separated from each other.

Organized by type

Files & Folders

app/
    app.module.js
    app.config.js
    layout/
        shell.html
        shell.controller.js
        shell.controller.spec.js
        topnav.html
        topnav.controller.js
        topnav.controller.spec.js
        footer.html
        footer.controller.js
        footer.controller.spec.js
    auth/
        auth.html
        auth.controller.js
        auth.directive.html
        auth.filters.js
        auth.route.js
    services/
        data.service.js
        localstorage.service.js
        logger.service.js
    customers/
        customer-detail.controller.js
        customer-detail.controller.spec.js
        customers.controller.spec.js
        customers.controller-detail.spec.js
        customers.module.js
        customers.route.js
        customers.route.spec.js
    sessions/
        sessions.html
        sessions.controller.js
        sessions.routes.js
        session-detail.html
        session-detail.controller.js
    css/

Directory layout

  • Files of the same function are together.
  • Easy to find related files.
  • Unit test files (specs) side-by-side with your client code, it is easier to keep them up to date since they are in sight, easy to TDD.
  • You could even go more specific if the app is larger, split files into sub-folders by types.
  • Recommended to medium and large apps. 

Organized by feature

Modules

  • Reusable software components.
  • Gives simplicity to our application.

A module should be...

  • Ability to use them in other applications.
  • Encapsulations of your code. exposing an API.

Specialized

  • Should have a very specific function.
  • Should solve the single problem that it's meant to solve.
  • Exposed API should be clean.

Independent

  • Should know the less possible of the other modules.
  • Communicate with others using events.

Decomposable

  • Simple to test individually.
  • Isolation from the other modules.
  • Other components should work without it.

Recomposable

  • Should fit with other modules in different ways.
  • Able to use in different version of the app

Substitutable 

  • Should be possible to substitute a module with others as long as it exposes the same interface.

Organizing modules

Module recomendation

App

Module1

Module2

Module3

Main module might not have actual objects in it, just a collection of sub-modules.

Sub-modules you want to add to the main module application

Name collisions

  • AngularJs modules do not provide any sort of namespacing that would prevent name collisions.
  • If the injector finds objects with the same name, one will override the other.
  • When collisions happen they are silent, no error is thrown, Angular injector takes the last one that was injected.

Avoiding name collisions

Name objects uniquely for each module. 

Use a simple camel-case prefix of two or three digits to represent the module.

Naming Objects

Controllers

- Costumers

CostumersCtrl

- CostumersController

- costumers.controller

As long as the objects names are consistent trough the project, we are ok .

Services

- Costumers

CostumersSvc

- CostumersService

- costumers.service

Directives*

- myAvatar

- myAvatarDrct

- my-avatar

Partial Views

- customersView.html

- customers.html

Uses a wrapping function to encapsulate private data in a closure 

The Module Pattern


var myModule = (function () {
  return {
    hello: function hello() {
      return 'Hello, world!';
    }
  };
}());

IIFE: Immediately Invoked Function Expressions.

Exposes a public interface. 

Loads asynchronously modules at runtime. 

Asynchronous Module Definition (AMD)

define(['amd1', 'amd2'],
  function myModule(amd1, amd2) {
    var testResults = {
        test1: amd1.test(),
        test2: amd2.test()
      },

      // Define a public API for your module:
      api = {
        testResults: function () {
          return testResults;
        }
      };

    return api;
  });

RequireJs

Creates a bundle file

Universal Module Definition (UMD)

//bar.js
module.exports = function (n) { 
    return n * 3 
};

//foo.js
var bar = require('./bar');

module.exports = function (n) {
    return n * bar(n);
};

CommonJs, Node-style modules.

BrowserifyJs

Task Automation

Grunt

Gulp

Testing

TDD

...

it('should have Customers controller', function() {
    // TODO
});

it('should find 1 Customer when filtered by name', function() {
    // TODO
});

it('should have 10 Customer', function() {
    // TODO -> Mock data
});

it('should return Customers via XHR', function() {
    // TODO ->$httpBackend 
});

// and so on

Karma & Jasmine

Mocha

Sample App

Angular

Browserify

Gulp

Karma & Jasmine

Less

Ng Materials

Thanks!

Angular Real World Apps

By Carlos Iván Mercado

Angular Real World Apps

  • 240