A simple introduction to AngularJS, Part 2 – Getting started

Ok, if you have read my first post in this series about getting started with AngularJS, you will know what AngularJS is, as well as why I am creating yet another introduction to it. In this part, I want to focus on getting started. The first baby steps in the road to building SPAs with Angular.

The first step is to set up a new application. In this case, let’s keep it ridiculously simple. It doesn’t have to be a big complicated solution and use big IDEs like Visual Studio. At least not in the beginning. IDEs have their place, but for now, adding a simple folder on the computer is enough to get started. This folder will be the “solution”. And Notepad will be the editor.

You are obviously more than welcome to use another editor. Notepad is in no way the only editor that was built with Angular in mind. But it, or very similar editors, are pre-installed on most development computers in the world.

I start by adding a single file in the “solution folder”. I call it index.htm. Inside the file, I create a basic HTML skeleton.

<!DOCTYPE html>
<html>
<head>
<title>A simple introduction to AngularJS - Part 2</title>
</head>
<body>
</body>
</html>

Ok, it’s beautiful, I know. And just imagine how awesome I must be considering that I could code all that without a single Google request. (That is actually not true, I had to Google the doctype…) And now that I am done talking crap, let’s carry on…

The next step is to include AngularJS. There are several ways to do so. The 2 main ones would be to either download it to the computer in some form, or piggyback on a CDN somewhere… If you want to use a CDN, there are loads of them out there. For example

https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js

In my case, I will download it. Why? Well, I guess I am old school… And there are actually situations when I am not connected to the internet. Having the libraries checked in are lifesavers in those situations…

If you want to download it, there is a big ass button on the AngularJS website. The button will always point to the latest stable release, and give you the option to download it either minified or uncompressed… I will get the minified version and put it in a Scripts folder inside my “solution folder”.

If you want to, you can also download it using either bower or nuget… The only thing with at least nuget is that you get ALL of Angular. That means you get all the different language resources, and all the different features. In this case, I only need the bare basics, so using nuget would get me a WHOLE lot of extra stuff I don’t need…

Ok, now that I have my AngularJS script, I will just add it to my head section to make sure it loads… Done!

Now that Angular is available on the page, it is time to turn the webpage index.htm into an AngularJS application, which is done by adding an attribute called data-ng-app to the html element like this

<!DOCTYPE html>
<html data-ng-app>
<head>
<title>A simple introduction to AngularJS - Part 2</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
</body>
</html>

As you can see, I have added data-ng-app to the html element. This identifies the page as an Angular “application”. It can be written in a couple of different ways. The most common one to see is ng-app. However, that is not valid HTML 5. Adding “data-“ in front of it makes it valid, and is the way I suggest adding it.

I had to look it up using my favorite search engine, but I now also know that HTML attributes without values are valid in HTML 5. They apparently mean boolean values, where adding it means it is true, not adding it means false… This is not what it means to Angular, but it makes adding data-ng-app without a value valid.

If you open the page in your browser of choice, you will now have an Angular application. It won’t actually do anything, but it will be an Angular app…

So, let’s make it do something… The first thing I am going to do, is to add a textbox to the page, including another “custom” attribute.

...
<body>
<input type="text" data-ng-model="prop" />
</body>
...

Running it now, will give you a textbox that has its value databound to a property called “prop”. However, it won’t do anything if you type in it… Actually, it will, behind the scenes, but you won’t see any of it… So to remedy that, I am going to add a funky string of text to the page

...
<body>
<input type="text" data-ng-model="prop" />
{{prop}}
</body>
...

As you can see, I have added the string {{prop}} to the page. The curly braces anclose the word “prop”, which is the same name that I set up as the “model” for the textbox. I will go back and explain what it all means in just a second, don’t worry. But before that, if you open the page in a browser and type something in the textbox, there will be some two-way data binding action going on

image

As you can see, the text being inserted in the textbox is being shown next to it. And it is being shown in real-time… If you “inspect” the element using the browsers development tools, you will see something like this

image

As you can see, the curly braced enclosed string has been replaced by the text being inserted into the textbox. This is Angular doing its magic. You will also see some new class values on some of the HTML elements. This is also Angular doing its magic…but ignore that for now…

Ok, so what is really happening here? Well, there are quite a few things going on… Some explicit, some implicit…magical unicorn style… Let’s go through them one at the time.

The first thing that happens when Angular is loaded is that it will read through the HTML DOM looking for attributes and double curly braced values (as well as custom elements, comments and css classes). If the attributes correspond to any that Angular knows about, they will get special treatment. I will get back to what that means later…

The first thing Angular will find, and care about, is the data-ng-app attribute. This identifies that this element, the html element, and all its children, form an Angular application.

Next, it finds the data-ng-model, which tells Angular that the textbox’s value should be data bound to a property called “prop”.

A property called “prop” on what? That’s the question you should be asking yourself right about now… I will get back to that, cause that is a part of the unicorn style, implicit magic stuff…

Next, Angular will find a double curly braced value. This tells Angular that the developer wants to output the value of the property “prop” at that location… It then remembers this, and removes the curly braces and content, hiding it from the user.

To be honest, for a VERY short time, those curly braces is visible on the screen, which for a small and quick app like this, this isn’t a problem. But for a larger, more complex page, where parsing might take a couple of milliseconds, it might look ugly. This can be solved using another attribute called “data-ng-cloak”…but that will be covered some other time…

Ok, so now that Angular is done parsing the page, it is pretty much done. At least until one starts typing in the textbox. Once text is being entered in the textbox, Angular gets notified, and makes sure that anyone interested in the value of the bound property, gets notified of the change. In this case, the curly braces…

That’s pretty much it. That is Angular in all its glory… So let’s get down to the slightly more complicated and technical… Let’s start by looking at that implicit thing that apparently has a property called “prop”…

When Angular finds a data-ng-app attribute, it knows that it is an Angular application. All Angular applications depend on being able to data bind values to something. This something is called a scope in Angular. So when Angular identifies a new application, it creates a brand new scope, which to be honest, is just a JavaScript object with the right prototype. The scope object is the link between the code and functionality, and the UI. It is the glue that makes data binding work…with some help…

The newly created scope is available to anything defined below the data-ng-app adorned HTML element. In this case, the entire application…

When Angular finds the data-ng-model attribute on the textbox, it looks at the property that is trying to bind to. In this case “prop”. It then looks at the scope object to see if there is a property named “prop” on it. In this case, there isn’t. But being that we are working with a nice and dynamic and untyped language like JavaScript, that doesn’t really matter. It doesn’t throw an exception or anything. It just sets up the data binding anyway. (To be honest, it isn’t specifically because it is JavaScript. Databinding in XAML ignores it in the same way, and that’s when using C#…just saying…)

The same thing happens when Angular finds the double curly brace. It looks at the value inside the curly braces and finds the string “prop”, which tells Angular that it wants to data bind against the property “prop” on the scope object. Once again, there is no property, but it sets up the binding anyway…

Next, when text is entered in the textbox, Angular listens to key presses on that control. When a key is pressed, Angular knows that the value is databound, and propagates the new value from the textbox to the scope object. Once the new value is set, it makes sure that any other control bound to that value is notified. in this case, the curly braces are, so they are notified, and writes out the value in the right place.

Side note: The double curly braces are from a JavaScript templating engine called Mustache. They work much in the same way as the following HTML would have done

...
<span data-ng-bind="prop" />
...

Where data-ng-bind is like data-ng-model except it is a one-way binding…

The only difference between double curly braces and data-ng-bind being that you don’t need the extra span tag. This means that they can effortlessly be placed inside of text without adding annoying extra HTML elements just to get data binding.

Ok, so that means that we have a model, and a view. That’s the MV, but what about a controller, or viewmodel to make it MVC or MVVM? Well, in Angular you use controllers. Controllers are where we put our logic. Where we manipulate the scope and handle changes made to the scope properties. Where we communicate with the server. Basically where we do all the logic stuff.

Side note: The people behind AngularJS doesn’t doesn’t seem to call it an MVC. They call it MV-anything or MV* or something else. I guess it is a way to stand out a bit, as well as a way to say that they aren’t strictly MVC…I guess… What we can al agree on, is that it is a part of the MV* family…

As you can see, Angular works without controllers. The data binding has no need for controllers to work. But the stuff we can do without a controller is very limited. Having that said, it is still nice to see that the view works without the controller, even if it is limited in functionality…

The controllers are actually just as separated from the view…at least if they are built in the right way. They can be instantiated and tested without the need for a view at all. Just as they should be…

This very clean separation between the view and the controller/viewmodel/controller is what we really want. It makes the code much more structured and less brittle. And it also makes it testable… (Who would have thought that I should have said that)

I won’t go into detail about controllers in this part. They will be covered together with modules in the next part…

But before I end this post, I want to try and give a high-level overview of how Angular works. I want to make sure that you understand that there are no unicorns and no pixie dust…and even if you didn’t think that, getting a grasp of how Angular does its thing can be very helpful.

As Angular parses the HTML, it looks at every single element, attribute, double curly brace, comment and css class. Each one of these get compared to a list of registered directives. If a directive with the same name is found, it is allowed to do its magic…

Ok…but what are directives, and what is the magic they are doing? Well…directives work as the link between the scope and the HTML DOM. Every directive, when found, gets to do “its thing”. It gets access to the scope, the HTML element it is connected to, as well as any other Angular “service” it needs. It then does whatever it feels like…

In this case, we have seen a couple of directives. Let’s look at the data-ng-model one.

Side note: The name of the directive is actually ngModel, using camel-casing, but when used in HTML, you use “dash-casing”. Someone, at some point called it “snake-casing”, which is what I have called it for a while now. But apparently “snake-casing” uses underscores, not dashes… Thank you Google for telling me, and making me feel like a moron…

Anyhow… The ngModel directive gets access to the element on which it is set, as well as the scope. It hooks up a handler for the keypress event (I think), in which it propagates the new value to the designated property on the scope.

It also adds a listener to the scope object, listening to changes to the designated property. Whenever the property changes, it changes the value in the HTML control…

Voila! Two way databinding magic, without actual magic! No unicorns or fairies were injured or killed during the development of Angular. That is not to say that there weren’t when the developers were being created though… But let’s hope not!

Ok…so that explains part one of the databinding. Part two is the scope, or actually something called the digest loop… I won’t go into detail about it here, but the simple explanation is that whenever the ngModel changes the scope, it also tells Angular that something has changed. Angular will then go through all listeners in the application, and tell them to see if they are interested in the change. If they are, they do their thing. Potentially telling Angular that the scope has changed again… This loop carries on until no more changes are being made. Or a semi infinite loop is found…

Combining the scope, the digest loop, and directives, is what drives Angular. It is a fairly simple concept, but that doesn’t make it less powerful or complex.

Ok, so now you have seen how to build a VERY simple Angular application, and got a quick overview of how Angular does its magic. And you have hopefully got a little curious about the next step.

The next part is about modules and controllers, and can be found here!

Cheers!

Add comment