Monday, March 20, 2017

AngularJS 1.x Best Practices

AngularJS Best Practices


Here we are going to discuss the best practices of AngularJS and why we should follow them for our development.

Let’s try to follow this as religiously as possible, as because this will not only make the code readable, but also will make it scalable, portable, reusable and efficient.

Below are the few tips and tricks that should be followed strictly:

Define 1 component per file, recommended to be less than 400 lines of code
Reasons:
1. One component per file makes it far easier to read, maintain, and avoid collisions with teams in source control.
2. One component per file avoids hidden bugs that often arise when combining components in a file where they may share variables, create unwanted closures, or unwanted coupling with dependencies.
The following example defines the app module and its dependencies, defines a controller, and defines a factory all in the same file.
/* avoid */
angular
   .module('app', ['ngRoute'])
   .controller('SomeController', SomeController)
   .factory('someFactory', someFactory);

function SomeController() { }

function someFactory() { }
The same components are now separated into their own files.
/* recommended */

// app.module.js
angular
   .module('app', ['ngRoute']);
/* recommended */

// some.controller.js
angular
   .module('app')
   .controller('SomeController', SomeController);

function SomeController() { }

/* recommended */

// some.factory.js
angular
   .module('app')
   .factory('someFactory', someFactory);

function someFactory() { }

JavaScript Scopes

Wrap Angular components in an Immediately Invoked Function Expression (IIFE).
Reasons:
  1. An IIFE removes variables from the global scope. This helps prevent variables and function declarations from living longer than expected in the global scope, which also helps avoid variable collisions.
  2. When your code is minified and bundled into a single file for deployment to a production server, you could have collisions of variables and many global variables. An IIFE protects you against both of these by providing variable scope for each file.
/* avoid */
// logger.js
angular
   .module('app')
   .factory('logger', logger);

// logger function is added as a global variable
function logger() { }

// storage.js
angular
   .module('app')
   .factory('storage', storage);

// storage function is added as a global variable
function storage() { }
/**
* recommended
*
* no globals are left behind
*/

// logger.js
(function() {
   'use strict';

   angular
       .module('app')
       .factory('logger', logger);

   function logger() { }
})();

// storage.js
(function() {
   'use strict';

   angular
       .module('app')
       .factory('storage', storage);

   function storage() { }
})();
The basic syntax of iife is the following:

funtion()(// all your code);

Designing:

Setting vs Getting

Only set once and get for all other instances.

Reasons:

A module should only be created once, then retrieved from that point and after.

/* recommended */

// to set a module
angular.module('app', []);

// to get a module
angular.module('app');

Named vs Anonymous Functions (Very Important)

Use named functions instead of passing an anonymous function in as a callback.
Reasons:
  1. This produces more reusable code, is much easier to debug, and reduces the amount of nested callback code.
  2. Protects code from minification.
/* avoid */
angular
   .module('app')
   .controller('DashboardController', function() { })
   .factory('logger', function() { });
/* recommended */

// dashboard.js
angular
   .module('app')
   .controller('DashboardController', DashboardController);

function DashboardController() { }
// logger.js
angular
   .module('app')
   .factory('logger', logger);

function logger() { }

Application Directory Structure

/**
* recommended
*/

app/
----- shared/   // acts as reusable components or partials of our site
---------- sidebar/
--------------- sidebarDirective.js
--------------- sidebarView.html
---------- article/
--------------- articleDirective.js
--------------- articleView.html
----- components/   // each component is treated as a mini Angular app
---------- home/
--------------- homeController.js
--------------- homeService.js
--------------- homeView.html
---------- blog/
--------------- blogController.js
--------------- blogService.js
--------------- blogView.html
----- app.module.js
----- app.routes.js
assets/
----- img/      // Images and icons for your app
----- css/      // All styles and style related files (SCSS or LESS files)
----- js/       // JavaScript files written for your app that are not for angular
----- libs/     // Third-party libraries such as jQuery, Moment, Underscore, etc.
index.html


Now let’s talk about Angular Controller As Syntax:

JS:

angularApp.controller(‘ControllerAsSyntax’, ControllerAsSyntax);

function ControllerAsSyntax(){
   var controllerInstance = this;
  
    controllerInstance.data = “Something”;
    controllerInstance.getSomeData = funtion(){
         return “something”;
    }
}





HTML:

<div= “demo” ng-controller= “ControllerAsSyntax as controllerAsSyntax”>
      {{controllerAsSyntax.data}}
      <!-- similarly you can access the method on controllerAsSyntax -->
</div>
,
For more you can refer here:

All the files establishing a common feature should be kept under one directory and it should not ideally contain any other files of another module, unless absolutely necessary.

The following link talks a lot about the things that we discussed. To know more about the best practices please read the article in the following article:


No comments:

Post a Comment