Angular Design

Items of note:
John Papa's style recommendations steer you in a good direction:

  • Use self-executing module (Immediately Invoked Function Expression — or IIFE)
  • Declare dependencies using the $inject syntax.
  • 'use strict'
  • var for the module and then declare the module's dependencies
  • module.config to handle navigation ($routeProvider). This also names a controller.
  • The controller is referred to in the config, and defined in a module.controller call. This has its list of dependencies

*

Example of Module declarations referring to Functions

    angular
        .module('crNetEdit.recs', ['crNetEdit.LocModule','ui.bootstrap'])
        .controller('RecSelectController', RecSelectController)
        .service('newNodeService', newNodeService)
        .directive('crRecSelect', crRecSelect)
    ;
 
    RecSelectController.$inject = [ '$scope', 'LocResource', 'NetworkRefresh', 'newNodeService'];

NOTE: Capitilization still needs to be sorted out.

Service Accessing Root Scope

I've got a few cases where the Service is bound to elements in the root scope of the module. Here's some tips on implementing this.

  • Think of a Service as something that connects models. Include them within a module that exposes the "view model" to directives where views can bind to the model.
  • Services are not injected with scope: http://stackoverflow.com/questions/22898927/injecting-scope-into-an-angular-service-function. You can however, bind the results of a service to a scope.
    • Preferred binding is via the isolate scope.
  • The Service will have a local ("private") var that holds the results provided by the service (populating some object typically).
  • The Service will return a method that returns the local copy.
  • The Service will update that local copy when it is called to provide its data.
  • Inside the controller for the overall app, declare a dependency on the service.
  • Also inside the controller for the overall app, extend the root scope with the "global" element that is to be shared.
  • Invoke the before-mentioned method on the service that returns the local copy and assign it to the $scope element being shared.

Examples

  • One example is the NetworkRefresh.segments() service and method. It uses a method that returns a local copy of the data setup by the module.
  • Another example is the RecSelectModule which binds to the external scope using an attribute on a Directive.

Binding Notes

  • View Model is used to expose the elements which are visible outside the module. These are the "public" elements.
  • Regular 'var' objects are used for the private elements that are shared amongst the functions and services within the module.
  • The View Model is bound using the controllerAs syntax. vm is the canonical name for the object whose dotted properties are the public "API".
  • In the HTML where the directive is brought in, there is an attribute which names an element in the scope. In the RecSelect example, the cr-rec-select Directive is in the splitMaps.html file and refers to the scope using the 'network' attribute. This attribute refers to the element in scope 'gjNetwork'.
  • The module's controller (not the directive's controller, although I could explore this once again) makes the connection between the View Model and the public elements within the Module.
  • Specifically, the internal variable representing the externally bound object(s) will be found using the $scope.$parent.<attrName>.

NOTE

It is likely that since
a) a Service is a singleton
b) the sharing of the data may as well be the sharing of the Service
that we could dispense with keeping a copy of the data in the Root Scope and only use the copy that is declared within the Service. Need to explore that.

Weak Spots & Gaps

  • Capitilization for constructors
  • Other naming conventions
    • Dotted notation for "namespace"
    • filenames
  • Handling of promises from Resources
  • The binding is still a little shaky.
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License