Matrix AngularJS

AngularJS, Build your App!!

  • Published on Thursday, 24 April 2014 23:21
  • Hits: 5187
User Rating:  / 2
PoorBest 

AngularJS was specially designed to build applications or web apps and not sites. If you just want to create an static site then forget about AngularJS (and go with JQuery if you need some javascript DOM manipulation), but if you are thinking about building an application with different views in different devices, many data manipulation and event handling then no doubt, you need to use angularJS.

The learning curve will be a bit high but the results in programming speed will be just expectacular!!.

Modules

Applications in AngularJS are structured in modules. A module can depend on other modules and a module can contain controllers, services, directives, filters, etc ..which we have already reviewed.

Some programmers use modules as classes, some others as just code libraries, but in any of the cases Modules are used to organize and structure your code allowing you to re-use it.

Having just controllers exposing the right data and functions to the view template works fine for small apps and the examples I have already written here, but it quickly becomes unmanageable in real apps. That is when you start organizing your application in modules.

For example let's continue with the movie Matrix example and let's see which modules we might create for this Movie structure:

  • The Module Movie which shows information about Matrix Movie, as for example a description and a list of Characters/Actors.
  • The Module Actor which contains information about any character in the movie (..in the example I just chose 5 of them).
  • The Module Picture Gallery which returns pics of a character.
  • The Module Trailer which shows a Movie Trailer. (..I will use it later on but not today).

 

Module Integration

Once we have defined the modules in our applications, we need to integrate them all. A movie has Actors, the Actors have Pictures, etc. This is done in the definition of each one of the modules. Let's start with the Movie Module. As checked before a Movie will have Actors in them so let's include the Actor Module in the Movie module

angular.module("Movie", ['Actor','ngResource','ngRoute'])

As you can check in the example, I am not only including modules created for this tutorial but also an AngularJS API Module:

  • ngResource: It provides interaction support with RESTful services via the $resource service providing high-level behaviors without the need to interact with the low level $http service. For making this AngularJS "Matrix" tutorial more helpful I will access the Movie RESTful server-side data sources using $resource, and $http service in the Actor and PictureGallery Modules.

and any Matrix Actor has a picture Gallery, so let's include this module in the Actor module

angular.module("Actor", ["PictureGallery", 'ngSanitize'])

Here I am also including another AngularJS API Module:

  • ngSanitize: It provides functionality to sanitize HTML. In this case the HTML returned from the server with the description of the Actor/Character selected

 

Module Communication

When a module is injected into another module, then the container module has access to all elements of the injected module, ..but what about if you want to create a communication channel between modules without taking into account which module is injected in which container??. Here is the Matrix example to illustrate how to manage that communication channel :)

This is what broadcasting has been created for. We have the following methods:

  • $broadcast: You will use $broadcast to send a message to any module that is "listening". You will use the $rootScope.
  • $on: You will use $on to listen a message which has been sent by a Module. You will use the $scope of your controller in this case

Le't s create a Service, in this case a factory, called messenger that will act as a messenger agent sending messages to any module which will be listening:

factory('messenger', function($rootScope) {
    var messenger = {};
    
    messenger.message = '';

    messenger.prepForBroadcast = function(msg) {
        this.msg = msg;
        this.broadcastItem();
    };

    messenger.broadcastItem = function() {
        $rootScope.$broadcast('handleBroadcast');
    };

    return messenger;

I have created this one in the PictureGallery, ..remember the first thing i mentioned about module communication, "container module has access to all elements of the injected module", so that service will be available for PictureGallery, Actor and Movie Modules.

Recommendation: It might be better to create a messenger module with all the services related to it.

Include Messenger in all the Modules

Then include the messenger service in any controls which will use it. In our case:

PictureGallery Module MainCtrl controller:

.controller('MainCtrl', ['$scope', 'messenger', '$http', function ($scope, messenger, $http)

Actor Module actor controller:

.controller('actor', ['$scope', 'messenger', '$http', function ($scope, messenger, $http)

Movie Module movie controller:

.controller('movie', ['$scope','Actors', 'messenger', function ($scope, actors, messenger) 

 

Include the Receiver in all the Modules

include the $on function handler:

MainCtrl controller $on handler: It gets the message and shows the character Image Gallery if the object type of the message is "showGallery".  The name of the character to show his/her Image Gallery will be in the object name.

$scope.$on("handleBroadcast", function(event, data)
{ var json = messenger.msg; obj = JSON.parse(json); $scope.character = obj.value; if (obj.type=="showGallery")
{
$http.get('./matrix.php?picture='+obj.value) .success(function(data)
{ $scope.photos = data;$scope.pictureVisibility=true;
});
} });

actor controller $on handler: It gets the message and shows the Actor information if the object type of the message is "showActor". The name of the Actor to show will be in the object name.

$scope.$on("handleBroadcast", function(event, data)
{
var json = messenger.msg; obj = JSON.parse(json); if (obj.type=="showActor")
{ $scope.character = obj.value;
$http.get('./matrix.php?actor='+obj.value) .success(function(data)
{ $scope.actor = data;$scope.actorVisibility=true;
});
} });

movie controller $on handler: It gets the message and shows the movie information if the object type of the message is "showMovie"

$scope.$on("handleBroadcast", function(event, data)
{
var json = messenger.msg; obj = JSON.parse(json); if (obj.type=="showMovie")
$scope.movieVisibility=true;
})

 

Include Messenger Sender in all the Modules

Finally, we need to have the modules broadcast the messages to each other. Here is the code per each Module, ...and remember that messenger.prepForBroadcast(myMsg) will $broadcast the message myMsg

Picture Gallery controller $broadcast execution: 

$scope.showActor = function(id) 
{ messenger.prepForBroadcast('{"type":"showActor","value":"'+id+'"}'); $scope.pictureVisibility=false; }

As you can see after broadcasting the message, the element used to show the Character Picture Gallery will hide away.

Actor controller $broadcast execution: 

$scope.showPictures = function(id) 
{ messenger.prepForBroadcast('{"type":"showGallery","value":"'+id+'"}'); $scope.actorVisibility=false; }
$scope.showMovie = function()
{ messenger.prepForBroadcast('{"type":"showMovie"}'); $scope.actorVisibility=false; }

In any of the cases after broadcasting the message, the element used to show the Actor will hide away.

Movie controller $broadcast execution: 

$scope.showActor = function(id) 
{ messenger.prepForBroadcast('{"type":"showActor","value":"'+id+'"}'); $scope.movieVisibility=false; }

And in this case just after broadcasting the message, the element used to show the Movie will hide away.

 

Directives

Let me introduce the biggest Module, or at least of the biggest, called ng and which is the angularJS Core Module. These will be the foundations of your application and it is divided in components, elements, services, filters, providers, ......and Directives.

Directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children. That means no more JQuery binds!!, ..remember that with AngularJS we will never need to worry about DOM manipulation :).

In our example we need to bind an action when any of the buttons, ..and of course that action will be triggered as soon as the buttons is clicked. So, taking a look to the huge list of directives as ngPaste, ngCut, ngCopy, ngBlur, ngFocus, ngSubmit, ngKeypress, ngKeyup, ngKeydown, ngMousemove, ngMouseleave, ngMouseenter, ngMouseover, ........, ngClick, ngDblclick, etc, it seems that the one in red is our candidate, ..isn't it?.

ng-Click to see character's info from the Movie Section:

<button class="btn btn-default" ng-click="showActor(actor.character)"><span class="glyphicon glyphicon glyphicon-user"></span></button>

ng-Click to see character's picture Gallery:

<button class="btn btn-default" ng-click="showPictures(actor.character)">Pictures <span class="glyphicon glyphicon-circle-arrow-right"></span></button>

ng-Click to go back to movie description:

 

<button class="btn btn-default" ng-click="showMovie()"><pan class="glyphicon glyphicon-circle-arrow-left"></span> Movie</button>

As I was writing this example I looked for a Picture Gallery and this is the first I found in AngularJS and that I have integrated here. If i have some time I promise to change it, as it does's look very good on mobile devices.

What is next??. I think you all like a bit of movement, you like some animation, ...and that is what I will be showing in the next session, to make it closer to a mobile application. Talking about movement, this song just came to my mind, ..ohh, my, it is so old!!

Check the result in this Demo

Download the Example Here

 Follow up this Mini Great Tutorial:

  1. AngularJS, Get in the Matrix
  2. AngularJS, Meet the MVC
  3. AngularJS, No more Dom Manipulation
  4. AngularJS, Build your App!!
  5. Animate your App!!
STORY BY:
Sepelka

Sepelka (JL Castellano)

FreakZion founder and Fortune 500 Company IT Manager. Developer, Consultant, Dreamer and passionate to get full potential for everything from a single project to a whole company with leadership, creativity and commitment.
Technology by itself is useless, but in our hands can turn dreams into reality, the forbidden into the affordable, boreness into fun and projects into businesses.

Check my LinkedIn Profile
Website: http://www.freakzion.com

Music You like..

IT News to be aware of ..

New in FreakZion...