AngularJS is a Javascript MVC framework from the fine folks over at
Google. The focus of Angular is building complex
HTML based client applications. Its design philosophy is data first, where your data will be updating the DOM.
Contrast this to a framework like JQuery where the DOM will update your data.
This is the ninth in a series of posts on AngularJS where we are using Chemistry data from the periodic table
to help us understand the framework. The others posts are
Note: AngularJS does not allow for more than one ng-app directive. When I have multiple angular posts on
the home page of my blog, only one application will work. I need to refactor the entire site to account for
this. All of that to say this, you are best clicking on a single article so you can see the pages in action.
On the AngularJS homepage you see the claim that Angular is "HTML Enhanced for Web Apps!"
What does this actually mean though? For me, it means directives, which allow us to extend HTML and create new HTML
markup. Let us pretend and call it our own HTML 6.
HTML, when initially created, was a subset of SGML, which is popular in the print industry. HTML, especially in the early
days, kept a lot of the print mentality. However, during the period when Web 2.0 applications emerged, it became
obvious that HTML was moving way
beyond it's print background and becoming an application platform itself.
Given it's print background and laborious standards process that defines the HTML specification, HTML is relatively fixed
platform. Your chances of getting a new tag into the standard for use in your application in the next ten years are
pretty close to zero. However, Google starts earning the superheroic name it gave AngularJS by solving this problem with
directives. To my knowledge, they are the only JavaScript framework that enables you to do this so far.
While we have seen directives previously, they have been attributes that allow us to markup existing HTML elements with
bits and pieces of Angular functionality. Examples of this have been ng-show or ng-repeat. For this post, we are
going to make a custom directive, which will allow us to create our own HTML tag.
The value of creating our own tags, is that it allows us to
start thinking of our HTML markup as a domain specific language. Throughout this series, we have been using Chemistry data
to explore Angular. In keeping with that theme, we are going to create a simple custom directive to display chemical
data in its own "HTML" tag called periodicchartelement. Cool things are starting to happen here people!
So how do we do this? First, similar to controllers, directives are defined on the module for our application via the
module.directive API. Within here, we can setup a small template. Our JavaScript would look something like
Of course, we can break the template into its own file by using templateUrl as we have discussed
earlier, which is the preferred approach.
We next define what part of our HTML our directive will be expanding. We do this by using restrict to
indicate the DOM element we are creating from the following options
'A' - The attribute of a DOM element. for example <div periodicchartelement="element">
'C' - class name
'E' - A new element name, for example <periodicchartelement></periodicchartelement>
There is also the ability creative directives tied to HTML comments with restrict:M. The restrict keyword
can also be combined together to in a manner such as ACM, indicating the directive applies to attributes, classes,
and comments.
Our directive function now creates a new HTML element, periodicchartelement.
For the example we are creating, we have changed a few things in comparison to previous posts.
Based on our introduction of services
last time, we have wrapped our periodic data in a service with a function called getElements(). Second, we have expanded the properties
of our JSON object used in the application to include fields about the periodicity of chemical elements. Here is an example
With that in place, let's create a directive that will allow us to display an element from the periodic table.
The first step is to create the directive function, we will create a new file, chemistryDirective.js and then hang
the directive off of our module and call it `periodicchartelement
You will notice several things. First, we are using the restrict keyword to explicitly identify this as a
HTML element by using the value of E. Second, we are loading a HTML template for display. Last, we are passing in two items, the element
from our JSON object and a cssType, which is a function from our scope to display our CSS class.
Our HTML markup is pretty basic. Notice though where we are setting a CSS class using ng-class and binding to the value
of cssType.
We have now created a new HTML element! It displays the atomic number, the atomic weight, atomic symbol and the name from
our JSON object of periodic data. Based on the element type, we then color code the element appropriately.
This is the most basic of introductions of creating directives with AngularJS,
next time, we will dig in deeper!
AngularJS is a Javascript MVC framework from the fine folks over at
Google. The focus of Angular is building complex
HTML based client applications. Its design philosophy is data first, where your data will be updating the DOM.
Contrast this to a framework like JQuery where the DOM will update your data.
This is the eight in a series of posts on AngularJS where we are using Chemistry data from the periodic table
to help us understand the framework. The others posts are
Note: AngularJS does not allow for more than one ng-app directive. When I have multiple angular posts on
the home page of my blog, only one application will work. I need to refactor the entire site to account for
this. All of that to say this, you are best clicking on a single article so you can see the pages in action.
In AngularJS, when we want to create common code to be shared across our application, we create services. In the Angular world,
the controller is the traffic cop, which directs data to your view for binding. Logic for retrieving that data falls to a
service.
Services are stateless object that have shared functions that can be used in multiple controllers or views. The functions on
services are also available throughout; they can be accessed in directives, controllers, filters, etc.
For an example of a real world service that I have used in the past…. When creating a select list in HTML for an AngularJS
application, you usually have an ID associated with a selected element from the list. Often you will
display all the properties of the JSON object. In JavaScript, to find this element, you need to loop through all
the elements in an array until you get a match on the key. Depending on the size of your application, you end up writing this
logic many, many times. To minimize this, I have written a helper application that creates an array that allows for
an element to be accessed by a key value, thus reducing the need for repetitive array looping.
Generally, there are two ways to create services within your application. The most common is to use module.service within
your application. The second is module.factory. There are a couple of other ways, but we will skip those. AngularJS
services are really singleton objects. The object from services are then available across your application via dependency
injection, which we will look at soon.
The main difference between the two service creation methods is how they are used. The module.service approach creates an
instance of a function. A good use case for this approach is the generic array lookup function mentioned above. The
module.factory approach is that the returned value is returned by invoking a function reference. This essentially allows you
to treat the service like a class that you can new to make new instances.
Once we create our service, we want to be able to use this within our application. This is done via the magical gremlins
that drive the Dependency Injection model in AngularJS. We just pass the service name to our controller when we instantiate
it. We showed this above, but just to be sure, by passing chemistryService to the controller, it is service is
available within the
controller scope
Let's look at a more advanced scenario. I am pretty much stealing this demo from my
Skyline Technologies
colleague Brian Mahloch. Brian came up with a great demo for demonstrating services
using the Periodic Data, which he kindly let me steal.
What we are going to do is determine the type of bonds two elements would make, based on the differences in their
electronegativity. We will create a service that does two things, calculate the differences in electronegativty and then
based on the difference determine the type of bond.
Our controller creation then gets updated so that we are injecting the service into the parameter list. Next,
since $scope is our conduit for the view to talk to the service, we create a function on the controller that will
consume the service when we have two elements selected.
Tying it all together, we have something like this.
We can now start to see how AngularJS provides a platform for creating web applications. With services, we are able to
encapsulate logic and use it within multiple controllers in our application.