AngularJS Directives

By Alex Vanston
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies

About this book

AngularJS, propelled by Google, is quickly becoming one of the most popular JavaScript MVC frameworks available, working to invert the development paradigm and bring data-driven modularity to the web frontend. Directives serve as the core building blocks in AngularJS and enable you to create reusable models that mold around your data structures and breathe new life into the intersection of HTML and JavaScript.

AngularJS Directives serves as an in-depth study of some of the core features of AngularJS and provides you with all the knowledge you need to create fully dynamic web applications that respond in real-time to changes in data. You'll learn how to build directives from the ground up as well as some of the best practices for architecting them. By the end of this book, you'll be able to create a web application comprised of multiple modules all working together seamlessly to provide the best possible user experience.

AngularJS Directives starts by investigating the best practices for single-page application development overall before diving into how AngularJS directives fulfill those goals. At each step, you'll learn both the how and why of what we're building, and by the end, you'll not only know the facts necessary to create a directive, but you’ll also have the knowledge to decide how best to assemble it.

You'll also learn why it's best to build applications with the data-model as your foundation, how to craft new dynamic modules that communicate with each other, how to build widgets that can be embedded in third-party websites, and even how to create custom inputs so your users can intuitively interact with your data. In AngularJS Directives, you'll learn all the necessary tools to begin architecting your own directives and how to use them in the construction of a more dynamic Web.

Publication date:
September 2013
Publisher
Packt
Pages
110
ISBN
9781783280339

 

Chapter 1. Designing Web Applications in 2013

The goal of this chapter is to provide a quick introduction to some principles that will help you create high quality code, specifically aimed at frontend web application development. For a fuller study, I strongly recommend the article, Patterns For Large-Scale JavaScript Application Architecture, by Addy Osmani.

 

An overview of good code


If you're reading this book, I'm going to assume you've done at least some programming work yourself, likely more than a little. During that time, I hope you've had the chance to see some great code. Perhaps it was your own, but more likely, at least for the first couple times you glimpsed it, it was someone else's masterpiece. You probably didn't necessarily know what made it great; you just knew that it was far better than anything you had ever been able to extract out of a keyboard.

On the other hand, almost anyone can identify bad code (unless it's their own, but that's a whole different book). The logical holes, the ignored errors, the horrifyingly inconsistent indentation; we've seen it all, often with our own name attached to the file, but somehow transforming that spaghetti mess into anything resembling those works of art that we'd previously marveled at continues to escape us. This book isn't about beautiful code, but it is about a framework which flexes its muscles most effectively when wielded in a manner optimized for frontend applications, and as such it's worthwhile for us to spend a chapter discussing some of the best practices for modern frontend web development.

For the purposes of our overview, we'll look at two basic tenets: modularity and data driven development. Before we examine those, however, I want to use the next section to address a common misunderstanding about frontend web development: adding more APIs is not always the answer.

 

We're not just talking about a lot of APIs


Often, when a backend developer first begins working on a frontend project, they believe that they can simply create an awesome API in the backend, call it with the frontend code, and have a complete frontend web application. When I first started developing frontend web applications, I wrote a lot of code that looked like the following:

$('#nextLink').click(function () {
  $.get('api/next', function (nextPage) {
    displayPage(nextPage);
  })
});

While the frontend technically handles both the user interaction ($('#nextLink').click()), and the display (displayPage(nextPage)), the real driver here is the backend API. The API handles the logic, the state, and makes nearly all the decisions about how the application should actually function.

In contrast, the frontend applications built on top of data modeling frameworks allow us to move away from that paradigm and instead position the client-side code as the primary driver. This is awesome for two reasons:

  1. It allows modern web developers to do 90 percent of the coding in the same language. This creates the potential for more code reuse, easier debugging, and all-round more efficient development, since even developers who speak both client and server-side languages fluently will lose some momentum when they have to switch between them.

  2. The user experience vastly improves when everything we need to run the application is already downloaded and available. Because the majority of the logic and application processing is done client side, we are no longer dependent upon network requests or additional downloads before moving the user forward. And as the JavaScript engines in all modern browsers get continually faster with each release, even computationally intense processes are becoming less and less of a limiting factor.

These reasons can make a significant difference in even the smallest of applications, even if it's only in your own peace of mind while developing. As you begin to tackle larger projects, however, especially if you're working on a distributed team, modular code that all builds on top of the same data-model becomes mission-critical; without it, each bit of functionality might expect a different property, flag, or (brace yourself) classname to represent the appropriate state for your application. In contrast, when your code is data-driven, everyone can work off the same built-in value map, allowing different pieces to connect far more seamlessly.

Now that we've clarified what frontend development isn't, let's gets back to the key principles that lead to great frontend application code.

 

Modularity


The principle of modularity is hardly specific to frontend web applications, and most developers these days recognize its usefulness, so I won't spend a lot of time here, but it's worth a quick overview.

The primary goal of modularity is to ensure that the code you write can be reused in different parts of the same application, or even in different applications entirely, without requiring extensive re-architecting. This also helps ensure that a change to the internal logic of one feature doesn't negatively impact the functionality of any other. In his article, Patterns For Large-Scale JavaScript Application Architecture, Addy Osmani describes it as:

Decouple app. architecture w/module,facade & mediator patterns. Mods publish msgs, mediator acts as pub/sub mgr & facade handles security.

In non-twitter speak, the basic goal is to make sure each feature/module keeps track of its own data/state/existence, is not dependent on the behavior of any other module to perform its own functionality, and uses messages to alert other modules to its own changes and appropriately respond to the changes of others.

We'll dive into modularity in great detail in the coming chapters, as it's one of the core principles of Angular Directives, so for now we'll leave this summary here, and continue to the next key principle for frontend web applications.

 

Data driven development


There are several different X-driven development ideologies in the world of software and web development, test-driven and behavior-driven being two of the most popular. data driven development (DDD from here on out) doesn't preclude any of these, and actually works simultaneously with many of them quite easily. DDD simply means using the structure of the data (or the model) as the foundation from which you build and make all other development design decisions. This is most easily explained by looking at an example, so let's start here, and then we will reverse the process to create a new application in the coming chapters.

In this example, we've created the quintessential frontend widget, a twitter feed display. This also serves as a good moment to highlight that not all web applications have to fill the entire page. Often, a web app is a simple widget like this, possibly something that can be embedded in third-party sites, and while there are some differences in structure, the basic organization and guidelines are still the same.

First, a quick snippet of some JSON data that we might use for this widget (we won't worry about the actual retrieving of data from Twitter right now):

[
  {
    "author" : "mrvdot",
    "text" : "Check out my new Angular widget!",
  },
  {
    "author" : "mrvdot",
    "text" : "I love directives!"
  }
  ...
]

The HTML:

<div ng-controller="WidgetController">
  <h3>My Tweets</h3>
  <p ng-repeat="tweet in tweets">
    @{{tweet.author}}: {{tweet.text}}
  </p>
</div>

And finally the JavaScript:

function WidgetController ($scope) {
  $scope.tweets = [];//loaded from JSON data above
}

While the preceding example does operate within the Angular framework, the basic structure here is representative of all good frontend architectures.

Let's first take a high-level view of what's happening here. The first thing to note is that the data itself is most important. I listed it first not because it was shortest, but to illustrate that the data is the foundation from which the rest of the code evolves. After the data, we move onto the HTML. This is most applicable in Angular, though it applies to other frameworks as well. In this model, once we have the data, we use the HTML to describe the view, how we want to display the data, and also (jQuery aficionados, brace yourselves) how we want the user to interact with that data. Only then, at the end, do we write the little JavaScript code needed to glue it all together as the controller. From here, let's walk through it stepwise to see how everything works together.

Loading the data

When we first initialize our application, the first thing we need to do is load our data. In Angular, this is most commonly done through a service, which, while a vital part of Angular development, is outside the scope of this book. For now, let's just assume that we've already loaded our data into $scope.tweets. We'll dissect $scope in great detail later in Chapter 5, Keeping it Clean with Scope, so for the purpose of this example, just know that it serves as the link between the view and our data.

Structuring our HTML

Let's revisit the main element of our widget, the tweet paragraph tag:

  <p ng-repeat="tweet in tweets">
    @{{tweet.author}}: {{tweet.text}}
  </p>

The first part of the HTML code uses the ng-repeat attribute to declare (again, remember we're building our HTML on top of the data-model, not receiving a model and remolding the HTML to reflect it) that we want to iterate through the array of tweets and print out for each the author's handle and their tweets in a paragraph tag.

Adding JavaScript

Finally, because we've focused on building the HTML on top of the data itself, our JavaScript is only a few lines:

function WidgetController ($scope) {
  $scope.tweets = [];//loaded from JSON data
}

With this approach, our JavaScript is nothing more than a function (attached to our element via ng-controller="WidgetController") that binds our tweets to a $scope object. We'll discuss the specifics of scopes and controllers later, for now just know that the scope serves as a bridge between the controller and our HTML.

Consider how we might have done this with jQuery (or a similar DOM manipulation library). First we'd have to iterate through all of the tweets and build the HTML string to insert into the message list. Then we'd need to watch for any new changes to our tweet array, at minimum append or prepend new items, or possibly rebuild the entire list if we can't rely on all our tweets coming in order.

Don't misunderstand, jQuery is an amazing library, and we'll go into extensive detail about how to use it in conjunction with Angular in the chapter on linking. The problem, however, is that jQuery was never designed to be a data-model interaction layer. It's great for the DOM manipulation, but trying to keep track of the DOM and the data at the same time gets tricky very quickly, and as anyone who has previously built an application using this structure can attest, adequate testing is nearly impossible.

 

Summary


Hopefully by now you're beginning to see that frontend web applications are far more than just a collection of Ajax calls with a master backend still running the show. And as such, principles such as modularity and data driven development are vital to successful and efficient development. Modularity helps us plug features together without worrying about undocumented interactions breaking our entire app. And DDD ensures that every bit of our code stands on the foundation of the data-model itself, so we can be confident that the user's view and interactions accurately reflect the true state of the application.

If you're still not convinced about everything, that's ok, we'll explore both of these principles in more detail throughout the coming chapters. For now, though, let's take the next chapter to explore what distinguishes Angular.JS from many of the other common JavaScript MVC frameworks available today.

About the Author

  • Alex Vanston

    Alex Vanston is a self-professed geek and an outdoor junkie fused together. During high-school he began teaching himself how to code and has been obsessed with learning new languages and better ways to solve problems ever since. He has been building web sites and applications professionally for the past seven years, for clients and companies around the world. Currently he lives in Denver, CO, where he loves hiking (5 14ers down, 49 to go), playing pickup sports, and water skiing when he can. He's the lead front-end developer for ZipKick, Inc, a travel startup taking off in San Francisco, CA. You can find him online at http://www.mrvdot.com, where he blogs about web development and tech.

    Browse publications by this author