AngularJS: Angular Way

Controlling complexity is the essence of computer programming. Brian Kernighan. Software Tools (1976)

Angular's main goal is to make the development of single page applications easy.

Another aspect, which is frequently neglected, is the framework's ability to help to control the complexity of the system.

The complexity control can be achieved by following several rules, promoted and restricted by the toolbelt itself, which is referred to as "The Angular Way".

The fact, that those rules exist, does not mean that you won't be able to do something the way you like, but it means that it will be hard to do that or hard to integrate your components with the angular stack.

Main Principles

  1. No DOM manipulations in Controllers!

    DOM should be manipulated mostly in the directives, and in some rare cases in services

  2. All non-angular actions should be introduced to 'angular world’ using $scope.$apply (and not $digest!)

    Example: user interactions, 3rd-party plugins/widgets, custom events.

  3. Minimum logic in controllers - they are for "glueing" things together.

    Business logic should live in Services

  4. $scope inheritance should be minimized.

  5. $parent.$scope usages should be minimized.

  6. Direct controller's $scope references in directives should be minimized.

    Components should not know about each others scope. Use attributes and bindings to wire things together.

  7. $scope.$on, $scope.$emit $scope.$broadcast and events should be used sparingly - use $watch on fields/getters instead.

  8. Make granular-sized components.

  9. Use dependency injection to communicate between components.

On the Way to Scalable and Maintainable Architecture

There are some additional principles which can help with the architectural design:

  • Functional division in project structure:

    • angular.module per functional module
    • A separate directory for each functional module
    • All components reside in the directory next to each other (see ngbp
  • Project structure reflects architecture

    • A single component per file.
  • Cohesive components with max encapsulation.

  • Max components granularity (smth. like unix-way).

  • State and behaviour are separated (dumb views, anemic models are OK)