Tuesday, June 28, 2016

Angular Js quetions

1. What are the differences between AngularJS module's Service, Provider and Factory?

Understanding AngularJS Factory, Service and Provider
All of these are used to share reusable singleton objects. It helps to share reusable code across your app/various components/modules.
From Docs Service/Factory:
  • Lazily instantiated – Angular only instantiates a service/factory when an application component depends on it.
  • Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory.

Factory

A factory is function where you can manipulate/add logic before creating an object, then the newly created object gets returned.
app.factory('MyFactory', function() {
    var serviceObj = {};
    //creating an object with methods/functions or variables
    serviceObj.myFunction = function() {
        //TO DO:
    };
    //return that object
    return serviceObj;
});
Usage
It can be just a collection of functions like a class. Hence, it can be instantiated in different controllers when you are injecting it inside your controller/factory/directive functions. It is instantiated only once per app.

Service

Simply while looking at the services think about the array prototype. A service is a function which instantiates a new object using the 'new' keyword. You can add properties and functions to a service object by using the this keyword. Unlike a factory, it doesn't return anything (it returns an object which contains methods/properties).
app.service('MyService', function() {
    //directly binding events to this context
    this.myServiceFunction = function() {
        //TO DO:
    };
});
Usage
Use it when you need to share a single object throughout the application. For example, authenticated user details, share-able methods/data, Utility functions etc.

Provider

A provider is used to create a configurable service object. You can configure the service setting from config function. It returns a value by using the $get() function. The $get function gets executed on the run phase in angular.
app.provider('configurableService', function() {
    var name = '';
    //this method can be be available at configuration time inside app.config.
    this.setName = function(newName) {
        name = newName;
    };
    this.$get = function() {
        var getName = function() {
             return name;
        };
        return {
            getName: getName //exposed object to where it gets injected.
        };
    };
});
Usage
When you need to provide module-wise configuration for your service object before making it available, eg. suppose you want to set your API URL on basis of your Environment like devstage or prod
NOTE
Only provider will be available in config phase of angular, while service & factory are not.
Hope this has cleared up your understanding about Factory, Service and Provider.


2.How does data binding work in AngularJS?

By dirty checking the $scope object

Angular maintains a simple array of watchers in the $scope objects. If you inspect any $scope you will find that it contains an array called $$watchers.
Each watcher is an object that contains among other things
  1. An expression which the watcher is monitoring. This might just be an attribute name, or something more complicated.
  2. A last known value of the expression. This can be checked against the current computed value of the expression. If the values differ the watcher will trigger the function and mark the $scope as dirty.
  3. A function which will be executed if the watcher is dirty.

How watchers are defined

There are many different ways of defining a watcher in AngularJS.
  • You can explicitly $watch an attribute on $scope.
    $scope.$watch('person.username', validateUnique);
  • You can place a {{}} interpolation in your template (a watcher will be created for you on the current $scope).
    <p>username: {{person.username}}</p>
  • You can ask a directive such as ng-model to define the watcher for you.
    <input ng-model="person.username />

The $digest cycle checks all watchers against their last value

When we interact with angular through the normal channels (ng-model, ng-repeat, etc) a digest cycle will be triggered by the directive.
A digest cycle is a depth first traversal of $scope and all its children. For each $scope object, we iterate over its $$watchers array and evaluate all the expressions. If the new expression value is different from the last known value, the watcher's function is called. This function might recompile part of the DOM, recompute a value on $scope, trigger an AJAX request, anything you need it to do.
Every scope is traversed and every watch expression evaluated and checked against the last value.

If a watcher is triggered, the $scope is dirty

If a watcher is triggered, the app knows something has changed, and the $scope is marked as dirty.
Watcher functions can change other attributes on $scope or on a parent $scope. If one $watcher function has been triggered, we can't guarantee that our other $scopes are still clean, and so we execute the entire digest cycle again.

If the $digest is dirty, we execute the entire $digest cycle again

We continually loop through the $digest cycle until either the digest cycle comes up clean (all $watch expressions have the same value as they had in the previous cycle), or we reach the digest limit. By default, this limit is set at 10.
If we reach the digest limit Angular will raise an error in the console:
10 $digest() iterations reached. Aborting!

The digest is hard on the machine but easy on the developer

As you can see, every time something changes in an Angular app, Angular will check every single watcher in the $scope hierarchy to see how to respond. For a developer this is a massive productivity boon, as you now need to write almost no wiring code, Angular will just notice if a value has changed.
From the perspective of the machine though this is wildly inefficient and will slow our app down if we create too many watchers. Misko has quoted a figure of about 4000 watchers before your app will feel slow on older browsers.
This limit is easy to reach if you ng-repeat over a large JSON array for example. You can mitigate against this using features like one-time binding to compile a template without creating watchers.

No comments:

Post a Comment