For this guide, adhere to the Angular 2 Style Guide or the Angular 1 Style Guide unless stated below, which supersedes those rules.
Topics for this document are in the same order as they are in the Angular 1 Style Guide.
IIFE
IIFE for every component. A build procedure should compile all files into one file, duplicate "use strict;"
lines are eliminated one is inserted at the top and finally the file is minified. This is possible because no global variables are used within the Angular scope. It is bad practice to use them and nearly forbidden when developing an Angular application.
Generate code without using superfluous IIFEs.
// controller.js
"use strict";
/**
* Describe controller's purpose.
*
* @param {module~dependency} dependency
*/
angular.module("module").controller("SessionsController", (dependency) => {
var variable1, variable2;
/**
* Describe function's purpose.
*/
function gotoSession() {
/* */
}
/**
* Describe function's purpose.
*/
function refresh() {
/* */
}
/**
* Describe function's purpose.
*/
function search() {
/* */
}
this.gotoSession = gotoSession;
this.refresh = refresh;
this.search = search;
variable1 = [];
variable2 = 'Sessions';
});
If needing an activation function as can be the case when invoking a controller for a directive, wrap everything within an activate
function.
// controller.js
"use strict";
/**
* Describe controller's purpose.
*
* @param {module~dependency} dependency
*/
angular.module("module").controller("SessionsController", (dependency) => {
this.activate = () => {
/**
* Describe function's purpose.
*/
function gotoSession() {
/* */
}
/**
* Describe function's purpose.
*/
function refresh() {
/* */
}
/**
* Describe function's purpose.
*/
function search() {
/* */
}
this.gotoSession = gotoSession;
this.refresh = refresh;
this.search = search;
variable1 = [];
variable2 = 'Sessions';
};
});
Controllers
Our goal is to make things more explicit and obvious.
controllerAs with vm
Supersedes the topics presented in the controllerAs with vm section.
We don’t require the use of using a variable like vm
within a controller, properties and methods can be assigned to this
when they need to. Just make sure to only assign to this
what needs to be accessible.
Bindable Members Up Top
Supersedes some topics presented in the Bindable Members section.
We don’t want all the bindable members at the top if it calls a function as the called functions shouldn’t be called before they are defined. Refer above for example on how to structure code in regards to placement of methods and properties.
Assigning Controllers
Supersedes some topics presented in the Assigning Controllers section.
If a controller is to be assigned within a view, it should be put into the template. This makes it easier and everything is contained within the template and module.
// config.js
"use strict";
function config($routeProvider) {
$routeProvider
.when("/games", {
templateUrl: "app/game/games.html"
});
}
angular.module("app").config(config);
Template:
<!-- games.html -->
<div ng-controller="GamesController as games">
</div>
Services and Factories
Services and Factories are formatted the same way and only return the collection of functions that should be visible from outside.
// factory.js
/**
* Describe the type.
*
* @typedef {Object} module~factory
* @property {Function} function1
* @property {Function} function2
*/
"use strict";
/**
* Describe factory's purpose.
*
* @return {module~factory}
*/
angular.module("app").factory("service", () => {
/**
* Describe function's purpose.
*/
function function1 () {
/* */
}
/**
* Describe function's purpose.
*/
function function2 () {
return function3();
}
/**
* Describe function's purpose.
*/
function function3 () {
/* */
}
return {
function1,
function2
}
});
Directives
There is no need to format the directive by returning a variable. This is a waste of memory and lines as there is nothing being done with the variable except to return it.
// directive.js
"use strict";
/**
* Describe the directive's purpose.
*
* @return {angular~directive}
*/
function directive () {
return {
bindController: true,
controller: "ControllerController",
controllerAs: "vm",
restrict: "AE",
scope: {
// scope properties
},
templateUrl: "path/to/tempate.html"
}
angular.module("module").directive("directive", directive);
}
Manual Annotating for Dependency Injection
We are removing manual processes and repeat code.
Manually Identify Dependencies
Dependencies shouldn’t use $inject
since we can inject the dependencies in the primary function when declaring the component.
// controller.js
"use strict";
/**
* Describe the controller's purpose.
*
* @param {angular~$scope} $scope
* @param {module~dependency} dependency
*/
angular.module("module").controller("SessionsController", ($scope, dependency) => {
// truncated to callout top section
Resolving Promises
Having promises inside controllers is a good thing, but we don’t want to have them in routes, as controllers and their functionality will be defined in static HTML or within a directive.
Route Resolve Promises
This is unnecessary, since the controller should be only included in the directive or element. This again keeps the code clean and functionality contained in the module.
JSHint and JSCS
Supersedes some topics presented in the JS Hint and JSCS sections.
We’ve decided to use ESLint instead of JS Hint. This provides us basically the same functionality, but we liked the customizability more. Refer to the ESLint Style Guide Section for more information on using ESLint. ESLint also gives the capabilities of what JSCS supplies since they have merged.