AngularJS

Understanding AngularJS

These are the questions I encountered while trying to wrap my head around it:

Q: What does it do?

A: With AngularJS, HTML is no longer just static elements waiting to be manipulated to go alive, they are the structure and the logic. “They extend HTML by teaching HTML new tricks.” E.g., with a drop down menu, traditionally we’d go:

<div>
  <ul>
    <li>Home</li>
    <li>Links</li>
    <li>About</li>
    <li>More</li>
  </ul>
</div>

If you look at the structure itself, you can’t actually tell if this is just an in-page list or a menu, or how it will interact with the page. However with Angular, HTML could be expressive in themselves:

<drop-down-menu ng-mouseover="dropdown()">
  <ul ng-repeat="item in items">
    <li>{{item}}</li>
  </ul>
</drop-down-menu>

You could see at a glance what this particular fraction of HTML is–a drop down menu–and what it does–drop down on hover.

 

Q: What is data binding? And the difference between ng-model, ng-bind, and {{}}?

A: With data binding, what users view on stage could be bound to a javascript object back stage. So as soon as the object updates, the view updates with it, without refreshing the page.

Traditionally we write functions to accomplish the same effect by: a) update the new data, b) set up a trigger or a callback function to use jQuery to substitute the content of a particular div every time the content updates. With Angular, we simply bind the div with the data, and let Angular deal with all the technicals of updates. The actual advantage of using Angular is, when one gets used to thinking this way, he or she could focus more on the functionalities of the app, rather than the means to realise it. It’s like thinking in FOREACH and EVERY instead of FOR LOOP–one layer above.

Differences:

  • ng-model is a two way binding, therefore usually used in form elements
  • ng-bind is a one way binding ($scope -> view), and in theory is the same with {{}}
  • {{}}: but in reality, this takes more time to process than ng-bind, plus the gibberish stays on page before AngularJS initialise

 

Q: What is Dependency Injection (DI), and what does it have to do with file dependencies like RequreJS?

A: Dependency Injection provides access to values and functions between Angular modules and controllers. There are five kinds [1]:

  1. myApp.Value(“keyword”, value)
  2. myApp.Constant(“keyword”, “Constant Value”)
  3. myApp.Factory(“myFactory”, function(){})Keep in mind that it is not the factory function that is injected, but the value produced by the factory function.
  4. myApp.Service(“myService”, myService): Created with NEW when injected, so myService is defined outside controllers. A service in AngularJS is a singleton JavaScript object which contains a set of functions. The functions contain whatever logic is necessary for the service to carry out its work.
  5. myApp.Provider(“myProvider”, function(){}): Providers in AngularJS is the most flexible form of factory you can create. When you look at the function creating the provider you can see that the provider is a JavaScript object. The JavaScript provider object contains a single $get() function. This is the factory function of the provider. In other words, the $get() function creates whatever the provider creates (service, value etc.). What is injected into the controller is the product created by the provider, not the provider itself.

All the dependencies referred to are singleton, except $scope.

The difference between DI and RequireJS:

  • RequireJS dependencies only happens once, in the beginning when the files load
  • AngularJS DI happens throughout runtime, having to reference and share all the values and functions they want to share

 

Q: How to communicate between controllers?

A: Create a factory or service, to take advantage of the Dependency Injection system Angular provides [2].

var app = angular.module("MyApp", []);

app.factory("UserService", function() {
  var users = ["Peter", "Daniel", "Nina"];

  return {
    all: function() {
      return users;
    },
    first: function() {
      return users[0];
    }
  };
});
app.controller("OneCtrl", ["$scope", "UserService",
  function($scope, UserService) {
    $scope.firstUser = UserService.all();
  }
]);
app.controller("AnotherCtrl", ["$scope", "UserService",
  function($scope, UserService) {
    $scope.firstUser = UserService.first();
  }
]);

 

Q: What are directories?

A: They are essentially the advanced version of html, e.g. a div with ng-app, ng-repeat, ng-show in [3].

 

Q: How to do the routings with Angular?

A: https://github.com/angularui/uirouter

In my case, in coffeescript, with RequireJS:

define ['angular', 'angular-ui-router'], () ->
  app = angular.module('myApp', ['ui.router'])

  app.config ($stateProvider, $urlRouterProvider) ->
    $urlRouterProvider.otherwise '/state1'

    $stateProvider.state 'state1',
      url: '/state1'
      templateUrl: 'partials/state1.html'

    $stateProvider.state 'state2',
      url: '/state2'
      templateUrl: 'partials/state2.html'

  angular.bootstrap document, ['myApp']

 

Q: How does animation in AngularJS work?

A: Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class attached to a HTML element within your website, you can apply animations to it. [4]

References:

  1. Animate the Angular way: http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html#how-to-make-animations-in-angularjs
  2. Using with Greensock: http://www.yearofmoo.com/2013/05/enhanced-animations-in-angularjs.html#greensock-integration

I had struggled to understand how $animate.enter() works, because I thought you were supposed to call it explicitly somewhere. But it turns out that the enter/leave/move is triggered by directory behaviours such as in ng-repeat, ng-view, and ng-switch [5].

 

Subscribe to get interesting updates:

Standard