Getting Started with Angular (Modules, Controllers)

I have started studying Angular framework a few weeks ago.  I always try to keep up with frameworks out there in the world to see if any of them can save me time and fill in specific needs for my projects.  I was attracted by apparent simplicity of Angular, judging by few demos I viewed.  

Here is the use case.  I have an application.  I would like to separate into modules, each consisting of one or more controllers.

I am going to put my app into a single JavaScript file called app.js.  There is only one line of code in it, creating my app, which is also a module.

var myApp = angular.module('myApp', ["myApp.user"]);

Let’s break it down.  I am creating the only global variable my application will have – my main app object. I am calling Angular’s module function, passing in module name.  The next parameter is an array of dependencies, in my case modules my app will depend on.  So far I only have one module – myApp.users.  Event though the name is just a string, I like dotted syntax – it helps me think hieratically.

Let’s take a look at users module next.

 

angular.module("myApp.user", ["utilitiesService"])
       .controller("loginController", ["$scope", "$http", "utilities", function ($scope, $http, utilities) {
           $scope.login = function () {
               utilities.showPleaseWait();
               $http.post(myApp.rootUrl + 'Login/ProcessLogon', { userName: $scope.userName, password: $scope.password }).success(function (data) {
                   utilities.hidePleaseWait();
                   //handle success, check result
               }).error(function (data) {
                   utilities.hidePleaseWait();
                   alert('Communication error');
               });
           };
       }]);

Let’s break down the module.  Again, you see module call.  This time I have one dependency – on utilitiesService.  It is unimportant to what it does in our case, but essentially it is just a group of methods most screens will use.  Then I create controller factory method.  There is an important distinction here.  All objects are created lazily in Angular, only when they are needed.  Hence, my function that sets up controller (the last parameter to controller() method call) is only called when I mention loginContoller in my html.  More on that later.  You see $scope as one of the parameters – I just need to add properties and methods to it that I will bind in my UI.  I am adding one method – login method.

Now, let’s look at the HTML of the view bound to login controller

<div class="row" data-ng-controller="loginController">
    <div class="span4 offset4">
        <div class="well">
            <legend>Login</legend>
            <form data-ng-submit="login()" method="POST">
                <label>User Name</label>
                <input class="span3" placeholder="Enter email address" type="text" name="userName" required data-ng-model="userEmail">
                <label>Password</label>
                <input class="span3" placeholder="Enter your password" type="password" name="password" required data-ng-model="password">
                <button class="btn-info btn">Login</button>
            </form>
        </div>
    </div>
</div>

You probably noticed that I did not have to add userName and password properties to $scope in my controller.  Angular will just create them itself.  I would have added them, but I had no default values for them, so I did not see a point in that.  You see ng-controller directive – Angular will find loginContoller and bind to it to the view.  You see a few field bindings – those are ng-modeldirectives.  You also see ng-submit.  This directive will handle form submission.  I could have usedng-click on the button instead.  login() method in that directive will call login function of the loginController  you saw above.

Now, the lest step is to inject the actual application.  I did so on html tag of my shell view.  Since I am using ASP.NET MVC, I actually did so in _Layout.cshtml.  Again, this is a hybrid app, and you can inject main app any which way you like.

<!DOCTYPE html>
<html data-ng-app="myApp">

 

That is it.  This completes the circle by injecting my app into html by using ng-app directive and giving it the module I created as my main app.

To summarize, you can create your central app object by creating a new module.  In that declaration you can supply all the modules your app depends on.  Then you can create those dependent module and create their controllers within module() / controller() call chains.  There is one big advantage of this approach over what you see in demos.  In most demos all controllers are global.  If you structure your app as above, you only have one global object – your main app object.

On a side note, prefixing ng- directives with data- is my personal choice.  It keeps Visual Studio from complaining about invalid html.  You can just use ng-.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s