JavaScript and Angular Best Practices
"Best Practices"
IIFE
(function () {
'use strict';
})(globalVars);
(Immediately Invoked Function Expression)
Modules
var module = module || {};
(function (module) {
'use strict';
module.something = function() {
// Do something interesting
};
})(module);
Variable Declaration
// avoid
_someFunction();
var someVariable = 3;
// I'm hoisted
function _someFunction() {
// do something cool
}
// recommended
var someVariable;
function _someFunction() {
// do something cool
}
someVariable = 3;
_someFunction();
JSLint
Module Methods
// avoid
angular
.module('app', [])
.controller('MainCtrl', function MainCtrl() {
})
.service('SomeService', function SomeService() {
});
// recommended
function MainCtrl() {
}
function SomeService() {
}
angular
.module('app', [])
.controller('MainCtrl', MainCtrl)
.service('SomeService', SomeService);
Controller "as"
// avoid
$stateProvider.state('main', {
url: "/main",
templateUrl: '/app/main.html',
controller: 'MainCtrl'
});
function MainCtrl($scope) {
$scope.someObject = {};
$scope.doSomething = function () {
};
}
// recommended
$stateProvider.state('main', {
url: "/main",
templateUrl: '/app/main.html',
controller: 'MainCtrl', // or MainCtrl as vm
controllerAs: 'vm'
});
function MainCtrl() {
var vm = this;
vm.someObject = {};
vm.doSomething = function () {
};
}
No Logic in Controllers
// avoid
function MainCtrl() {
var vm = this;
vm.doSomething = function() {
if (vm.benchPress < 300) {
return 'Ha ha ha';
}
return 'not bad!';
}
}
// recommended
function MainCtrl(someService) {
var vm = this;
vm.doSomething = function() {
someService.doSomething();
}
}
Services
// avoid
function AnotherService() {
var someValue = '';
return {
someValue: someValue,
};
}
angular
.module('app')
.factory('AnotherService', AnotherService);
// recommended
function AnotherService() {
var AnotherService = {};
AnotherService.someValue = '';
return AnotherService;
}
angular
.module('app')
.factory('AnotherService', AnotherService);
Directives
// Presentation
angular.module(appName).directive('brkShowSomething', [_brkShowSomething]);
function _brkShowSomething() {
var directive = {
restrict: 'E',
};
return directive;
}
// <brk-show-something></brk-show-something>
// Add behavior
angular.module(appName).directive('brkDoSomething', [_brkDoSomething]);
function _brkDoSomething() {
var directive = {
restrict: 'A',
};
return directive;
}
// <brk-show-something brk-do-something></brk-show-something>
Directive Link vs. Controller
angular.module(appName).directive('brkMyBadAssDirective', [_brkMyBadAssDirective]);
function brkMyBadAssDirective() {
var directive = {
restrict: 'E',
link: _link,
controller: Controller,
controllerAs: 'vm'
};
return directive;
}
function _link(scope, element, attrs) {
// ALL dom manipulation goes here
// wiring up events, etc...
// I don't get injected but I have access to element
}
Controller.$inject = ['SomeService'];
function Controller(someService) {
// I'm doing logic and data binding type stuff
// I execute before link does
}
Performance
- Use $watch very sparingly
- $scope.$watch('someVar', function(){});
- DO NOT watch functions
- This includes the view
- Whenever possible, use 1 time binding (1.3)
- {{ :: someVar }} or ng-repeat="foo in :: foos"
Thank You
JavaScript and Angular Best Practices
By Dale Alleshouse
JavaScript and Angular Best Practices
- 1,571