Getting started with AngularJS
As you've increasingly used JavaScript and jQuery in your websites, you might be itching to take things a step further and build more complex user interfaces. For example, check out Virgin America's website. Notice how much interaction they have - when you click a destination city, new options are presented in place. Everything is super snappy and interactive. Take a moment to think about how difficult this would be to implement with just jQuery.
To build complex user interfaces like these, a new set of tools has evolved called client-side MVCs. MVC stands for model-view-controller, which is a way of setting up user interfaces that separates out the code into three interconnected parts: model, view, controller. A client-side MVC provides structure for your JavaScript code and automates common tasks. AngularJS is one of the most popular client-side MVCs. To start learning how to use it, we're going to build a simple app to manage all the students in a class. With Angular, we can add, edit and delete students as well as filter them on a single page, with relatively little work.
To get started, let's download Angular from the AngularJS homepage. Click the download button, and then a pop up window will present you with some options. Leave the selected branch at the number marked "stable". Then choose the uncompressed version which offers better debugging and development capabilities than the minified version. Then right click on the "Download" button and select "Save linked file as…", naming it angular.js. This is the core angular code that your application will depend on to run.
We'll start by creating a project directory called ‘student-roster’. Inside that folder, we can create folders called lib, js and css. Let's put the file angular.js inside of lib. I’m using Bootstrap, so I’ll put the bootstrap.min.css file in the css folder.
To create an application with Angular, we need to start off by creating a file called app.js in the top level of the project directory. For now, it only needs this one line of code:
student-roster/app.js
var studentRoster = angular.module('studentRoster', []);
The first argument to angular.module is the name of our app, which we are calling studentRoster. The second argument is any dependencies that the app might have; since our app has none, we will leave that array empty for now.
Just so we can make sure the app is actually loading, let's create a skeleton index.html file, also in the top level of our project directory, and then we'll open it in the browser:
student-roster/index.html
<!doctype html>
<html>
<head>
<title>Student App</title>
<script src="lib/angular.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="css/bootstrap.min.css">
</head>
<body>
</body>
</html>
First, we include the usual tags for doctype, html, head, and body. Then inside of the head we set the title of our app, load the lib/angular.js file, followed by our app.js file, and lastly a link to the bootstrap.min.css file in our css folder. Be sure to notice the load order - we have to load angular.js first, and then the app.js file.
At this point, we'll see a blank page. But if we open the JavaScript console and type studentRoster, we should get an object returned. This object is actually our new Angular app. Since we haven't written any code yet, there's not much to see there besides the name property. Let's write some code to display a list of current students.
In Angular, we use controllers to handle the logic of the app. Let's create our first controller and populate it with some sample data so that we have students to list. We will get to dynamically adding students with a form later. Create a file called StudentsController.js inside of your js folder, and then add this code to it:
student-roster/js/StudentsController.js
studentRoster.controller('StudentsCtrl', function StudentsCtrl($scope) {
$scope.students = [
{ name: "Sam Schmidt" },
{ name: "Jessica Martin" },
{ name: "Sandy Smith" },
{ name: "Ryan Samuels" },
{ name: "Brentwood Davis" }
]
});
In this file, we are calling the controller() method on our app studentRoster, which creates a controller. As arguments, we're passing in the name of the controller - StudentsCtrl - and a function that holds the controller's logic. This is similar to the way we created our app object by passing the name 'studentRoster' to the angular.module() method in our first file. We pass in a name as the first argument, and any other information the method needs as the second argument. The controller needs a function as that second argument.
Notice too that our controller function has a parameter called $scope. We've added an array of student data as a property of that $scope, and we'll use this data to populate our page. In Angular apps, data that is used to populate the page is called a model.
Now, let's display our sample student data. Make your index.html file look like this:
student-roster/index.html
<!doctype html>
<html ng-app="studentRoster">
<head>
<title>Student App</title>
<script src="lib/angular.js"></script>
<script src="app.js"></script>
<script src="js/StudentsController.js"></script>
<link rel="stylesheet" href="css/bootstrap.min.css">
</head>
<body>
<div class="container" ng-controller="StudentsCtrl">
<div class="row">
<div class="col-md-12">
<h2>Student List</h2>
<ul>
<li ng-repeat="item in students">
{{item.name}}
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
If we refresh the browser, we should see a list of the sample students!
Let's look through the changes we've made. First, we have added <script src="js/StudentsController.js"></script> into the <head> tag, to load our controller. Again, be sure to notice the load order. We have to load the controller file after the app.js file, and both of them have to be loaded after angular.js.
The ng- attributes we've added to our HTML tags are called directives in Angular (ng-app, ng-controller, and ng-repeat). They are used to extend the HTML with dynamic content and special behaviors. When your Angular app boots, it looks at these attributes, attaches the specified behavior to each element, and updates the DOM if necessary. The final version of what's rendered in the browser is called a view in Angular.
The first directive we have is ng-app="studentRoster" that we added to the <html> tag at the top of the file. This tells Angular that our entire web page will be controlled by Angular. If we only wanted a part of it to be controlled, we could add that directive to another element in our page, such as <div ng-app="studentRoster">.
Next we have the ng-controller directive. As you might expect, this designates the controller for the element where it is placed. By adding it to the <div>, we’re specifying that any directives inside of that <div> should refer to the StudentsCtrl controller, and any data that it pulls should come from the $scope in that controller.
Lastly, the ng-repeat directive is used to iterate through data that is stored in the $scope via the controller. item in students says to take each element in the students array and refer to it as item. Since we defined ng-controller in a parent <div>, Angular knows that to find that students array it must look in the StudentsCtrl controller. We then use the double curly braces to display the name property of each item. Just so you know, the word item isn’t special - this could be called "student in students" or anything else just as well. Angular developers use item a lot, so we'll stick with that for clarity.
It's important to remember that in order for a given directive to have access to a specific controller, the directive must be nested inside of an element with that controller defined via ng-controller.
That was a lot to take in! As you can see, directives serve a variety of different purposes. But they all share the common job of dealing with display logic and have direct access to $scope. Check out the AngularJS Documentation on directives and the [AngularJS API Docs}(https://docs.angularjs.org/api) for directives you can use.
Summary
Download a non-minified version of AngularJS.
Create an app.js file to start the Angular app:
app.js
var studentRoster = angular.module('studentRoster', []);
Use the ng-app directive in the <html> tag at the top of the index.html page, include the controller in a <script> tag, and use the directive ng-controller to set the controller for a particular section of the page:
student-roster/index.html
<!doctype html> <html lang="en" ng-app="studentRoster"> <head> <meta charset="UTF-8"> <title>Student App</title> <script src="lib/angular.js"></script> <script src="app.js"></script> <script src="js/StudentsController.js"></script> <link rel="stylesheet" href="css/bootstrap.min.css"> </head> <body> <div class="container" ng-controller="StudentsCtrl"> <div class="row"> <div class="col-md-12"> <h2>Student List</h2> <ul> <li ng-repeat="item in students"> {{item.name}} </li> </ul> </div> </div> </div> </body> </html>
The directive ng-repeat will loop through an array and you can display any information about the element in that array by using {{ }} double curly brackets and using whatever you named each item in the ng-repeat directive.
student-roster/js/StudentsController.js
studentRoster.controller('StudentsCtrl', function StudentsCtrl($scope) {
$scope.students = [
{ name: "Sam Schmidt" },
{ name: "Jessica Martin" },
{ name: "Sandy Smith" },
{ name: "Ryan Samuels" },
{ name: "Brentwood Davis" }
]
});
Make sure to include$scope when you declare the controller function. This $scope is scoped to within this controller and you need to use it to create properties or add methods to this controller.