Angularjs Anti-Patterns
The List ● Using $() instead of angular.element() ● Using jQuery to manipulate the DOM ● Looking at $scope.$$phase ● Not making ng-model an object ● Controllers doing too much or too bloated o Manipulating DOM or model/data o Throwing everything on $scope o Overusing $rootscope ● Not doing things the “Angular” way o Programing like you would in jQuery o Manipulating the view instead of the model o Not using Angular built-ins ($timeout, ng-show, ng-click, etc.) ● Not encapsulating 3rd party libraries in an Angular service
$() vs. angular.element If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite."“ Thus, angular.element is $(), so just use angular.element. Side note: don’t wrap in $element in a directive in angular.element, it already is one. From the docs:
jQuery DOM manipulation jQuery DOM manipulation isn’t detected by Angular’s dirty checker. Generating DOM with jQuery doesn’t create any Angular bindings. From the docs: Stop trying to use jQuery to modify the DOM… . Really. That includes adding elements, removing elements, retrieving their contents, showing and hiding them. Use built-in directives, or write your own where necessary, to do your DOM manipulation “
$scope.$$phase For future-proofing reasons, you should not use $$phase “ From Angular: Typically $scope.$$phase is used to conditionally call $apply. Instead, move the $apply to where you know you’re outside Angular. If nothing else, use $timeout. Code example
ng-model not an object Code example If ng-model is a primitive type (string, number, boolean, null, undefined) any references in a child controller or directive won’t be doubly bound. If it’s a complex type (object or array), it will be doubly bound. Always make ng-model an object.
Controller Bloat Don’t just throw everything on $scope or you’ll end up with $scope soup. Think of $scope as the public interface from your view to your data. Only expose what you need in the view. This goes for $rootscope as well. Think of $rootscope as the global namespace, and we all know not to pollute the global namespace.
Controller Bloat Controllers should be small and lean. Things that don’t belong in a controller: ● DOM manipulation (belongs in a directive) ● Ajax or $http (belongs in a service) ● Model/data (belongs in a service) ● Model/data manipulation (belongs in the same service as the data) ● Business logic (belongs in a service) Exercise: convert bloated controller to lean controller
The “Angular” Way Exercise: convert jQuery to Angular Programing in Angular is very different than programming in jQuery When using Angular, try not to manipulate the view (DOM), instead manipulate the model (data and how it is presented) Don’t forget about all the Angular built-in goodies like ng-show, ng-click, etc.
3rd Party Libraries When using 3rd party libraries, always wrap them in an Angular service. angular.module(‘myApp’).factory(‘_’, function() { return window._; }); angular.module(‘myApp’).controller(‘myCtrl’, function(_) { // can now use library as _ });
3rd Party Libraries By wrapping the library, you now allow Angular’s dependency injection to handle everything. This also makes testing easier as you can now inject a mock of the library into the unit test.

Angularjs Anti-patterns

  • 1.
  • 2.
    The List ● Using$() instead of angular.element() ● Using jQuery to manipulate the DOM ● Looking at $scope.$$phase ● Not making ng-model an object ● Controllers doing too much or too bloated o Manipulating DOM or model/data o Throwing everything on $scope o Overusing $rootscope ● Not doing things the “Angular” way o Programing like you would in jQuery o Manipulating the view instead of the model o Not using Angular built-ins ($timeout, ng-show, ng-click, etc.) ● Not encapsulating 3rd party libraries in an Angular service
  • 3.
    $() vs. angular.element IfjQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite."“ Thus, angular.element is $(), so just use angular.element. Side note: don’t wrap in $element in a directive in angular.element, it already is one. From the docs:
  • 4.
    jQuery DOM manipulation jQueryDOM manipulation isn’t detected by Angular’s dirty checker. Generating DOM with jQuery doesn’t create any Angular bindings. From the docs: Stop trying to use jQuery to modify the DOM… . Really. That includes adding elements, removing elements, retrieving their contents, showing and hiding them. Use built-in directives, or write your own where necessary, to do your DOM manipulation “
  • 5.
    $scope.$$phase For future-proofing reasons,you should not use $$phase “ From Angular: Typically $scope.$$phase is used to conditionally call $apply. Instead, move the $apply to where you know you’re outside Angular. If nothing else, use $timeout. Code example
  • 6.
    ng-model not anobject Code example If ng-model is a primitive type (string, number, boolean, null, undefined) any references in a child controller or directive won’t be doubly bound. If it’s a complex type (object or array), it will be doubly bound. Always make ng-model an object.
  • 7.
    Controller Bloat Don’t justthrow everything on $scope or you’ll end up with $scope soup. Think of $scope as the public interface from your view to your data. Only expose what you need in the view. This goes for $rootscope as well. Think of $rootscope as the global namespace, and we all know not to pollute the global namespace.
  • 8.
    Controller Bloat Controllers shouldbe small and lean. Things that don’t belong in a controller: ● DOM manipulation (belongs in a directive) ● Ajax or $http (belongs in a service) ● Model/data (belongs in a service) ● Model/data manipulation (belongs in the same service as the data) ● Business logic (belongs in a service) Exercise: convert bloated controller to lean controller
  • 9.
    The “Angular” Way Exercise:convert jQuery to Angular Programing in Angular is very different than programming in jQuery When using Angular, try not to manipulate the view (DOM), instead manipulate the model (data and how it is presented) Don’t forget about all the Angular built-in goodies like ng-show, ng-click, etc.
  • 10.
    3rd Party Libraries Whenusing 3rd party libraries, always wrap them in an Angular service. angular.module(‘myApp’).factory(‘_’, function() { return window._; }); angular.module(‘myApp’).controller(‘myCtrl’, function(_) { // can now use library as _ });
  • 11.
    3rd Party Libraries Bywrapping the library, you now allow Angular’s dependency injection to handle everything. This also makes testing easier as you can now inject a mock of the library into the unit test.

Editor's Notes

  • #9 Lean controller answer: http://jsfiddle.net/straker/t8dLzws3/
  • #10 Angular answer: http://jsfiddle.net/straker/kL5wdnbr/