Modern Web Application Development
Single Page Application Development using AngularJS
JavaScript Overview
Static Page: The web isn’t always as responsive as it could be. You would expect entering data in a web page would generate some sort of response… but nothing happened.
Interaction is two-way communication.
But JavaScript Talks Back. JS turns a web page into an interactive. JavaScript brings a web page to life by allowing it to respond to a user’s input. JS can turn a web page interactive application as opposed to a static, life less page.
Modern Web Page JS sits with HTML and CSS as one of three pieces of Modern Web Page Construction.
HTML provides the Structure CSS adds the Style
JS puts the action (injection functional sizzle, allowing the page to take action). JS springs into action when the user asks the page to perform a task.
Your Web browser can handle HTML, CSS and JavaScript.
Alerting the user the with a function. JS alert() function and passing it the text you want to display. JS alert() is a pop-up window, or box, that you can use to display information to the user.
Functions are reusable piece of code that perform common tasks.
Data Types:
JS uses three basic data types: text, number, and boolean.
var variablename = initial value; // variable names use CamelCase
lowerCamelCase is used to name multiWord variables. the first word is all lowercase, but additional words are mixed-case.
const constantname = constant value;
A piece of data is undefined when it has no value.
X = NaN; NaN is a value that isn’t a number even though you’re expecting the value to be one. parseInt() and parseFloat() converts text to a number.
Use getElementById() to grab the data from your Web page.
The key to accessing a web page element with JavaScript is the id attribute of the HTML tag:
<input type="text" id="cakedonuts" name="cakedonuts" />
The id attribute is what you use to access the form field in JavaScript code
The id attribute uniquely identifies any element in a page. The name attribute uniquely identifies a field within a form.
isNan() function
Client’s window width and height
The client window is only the part of the browser window that displays a web page. document.body.clientWidth
document.body.clientHeight
Script Life Cycle
1. The browser is launched 2. User enters URL in address bar
3. The page is loaded from the web server – HTML, CSS, JS and all 4. The onLoad event fires, JavaScript variables are created and initiated. 5. The user closes the browser or reloads the page
6. The script stops, JS cleans up all variables, and the page is closed.
Scope of variables:
Local Variables limited to specific block of code, such as a function
Arrays stores multiple pieces of data in a single place. var showtime = new Array();
showtime*0+ = “12:30”; var showTime = *“12:30”, “2:45”, “5:00”, “7:00”+; Functions function name() { body }
Passing information to functions: function name(arguments) { body
}
Returning data from functions: return value;
Callback Functions: Which are called by the browser, instead of your own code. The most common use of callback functions is in handling events.
<body onload=”initSeats()”>
<img …. Onclick=”showSeatStatus(26)”>
Using Function References You can assign a function reference directly in a JS code.
window.onload = initSeats; // There are no parantheses following the function name because you don’t want to run the function; you just want to reference it.
Anonymous Functions: It is a nameless function that handles the event. window.load = function() { initSeats(); } document.getElementById(“seat26”).onclick = function(evt) , showStatus(26); }
An event object is passed into event handler, in this case evt argument. The event object contains information specific to each different event.
Regular Expressions A regular expression is used to match patterns in text. Pattern involves physical attributes of a person.
Pattern = Tall, no glasses, short hair.
The pattern describes physical properties of a person that are then matched against actual people. Regular expressions allow you to do the same kind of pattern matching with strings.
A text pattern involves a certain sequence of characters.
Pattern = ##### This pattern involves a sequence of exactly five numeric digits. All Regular Expressions are enclosed by forward slashes. / expression /
Within the expression, a collection of special symbols known as metacharacters are used in conjunction with letters and numbers.
(dot) . Any character other than a new line \d Any numeric digit
\w Any alphanumeric character \s A whitespace character
^ String must begin with the pattern (The string being matched can’t have any text preceding the pattern)
$ The String must end with the pattern. (The pattern must be the very last characters in the string).
Examples:
/./ (Any Single Character) “A” or “%” or “7” /\w/ (Any Alphanumeric) “A” or “7”
/\d/ (A single digit) “7” or “2nite” or “catch22”
/^\d/ (One digit at the beginning of a string) “7” or “007” or “2nite” /\d\d$/ (Two digits at the end of a string) “catch22”
/\d\d\d/ (Three digits in a row) “007”
/^cat/ (cat appearing at the beginning of a string) “catch22” /cat$/ (cat appearing at the end of a string) “incat” /^\d\d\d\d\d-\d\d\d\d$/
Quantifiers precede within a regular expression, and provide control over how many times a sub-pattern appears in a sub-pattern.
{n} sub-pattern must appear exactly n times in a row.
* sub-pattern is optional and can appear any number of times ? sub-pattern is optional, but can only appear once if does appear + sub-pattern is required, and can appear any number of times
( ) used to group together sub-patterns much as you group together mathematical expns
Examples
/^\d{5}-\d{4}$/ A zip code pattern.
/\w*/ Matches any number of alphanumeric characters, including an empty string /.+/ Any character must appear one or more times… matches a non-empty string /(Hot)? ?Donuts/ Matches either “Donuts” or “Hot Donuts”
Validating data with regular expression var regex = /^\d{5}$/;
The regular expression matches a 5-digit ZIP code. $: This object literal automatically creates a RegEx object.
If(!regex.test(inputField.value)) // The zip code is invalid
Date pattern: MM/DD/YYYY or MM/DD/YY /^\d{2}\/\d{2}\/\d{2,4}$/ Phone Number pattern: \^\d{3}-\d{3}-\d{4}$/
Email: /^\w+@\w+\.\w{2,3}$/
Creating space with DIV In order to display description on the page instead of alert box, we first need to define a physical area on the page as an HTML element. <div> should work fine for description text appears as its own paragraph.
<div id=”sometext”></div> innerHTML is used to set the content on the page. document.getElementById(“sometext”).innerHTML = “You are <strong> not </strong> alone”;
The DOM sees a web page as a hierarchical tree of nodes. Your page is a collection of DOM nodes. DOM nodes are classified according to their node types.
Climbing the DOM tree with properties:
nodeValue The value stored in a node, only for text and attribute nodes (note elements) nodeType The type of a node, such as DOCUMENT or TEXT, but expressed as a number.
childNodes Arrays containing all of the child nodes beneath a node, in the order that the nodes appear in the HTML code.
firstChild The first child node beneath a node. lastChild The last child node beneath a node. Document.getElementById(“sometext”).nodeValue
Objects link variables (properties) and functions (methods) together inside a storage container. The dot operator references a property or method from an object
A constructor is responsible for creating an object. Every custom object requires its own constructor, which is named the same as the object.
Example: Write a constructor for a Blog object that creates and initializes properties for the date and body text of a blog entry.
Function Blog(body, date) { this.body = body;
this.date = date; }
var blogEntry = new Blog(“Got the new cube”, “08/04/2013”);
An Object class is a template, while an object instance is the thing created from the template.
Defining Objects:
function Card(name, address, work, home) { this.name = name;
this.address = address; this.workphone = work; this.homephone=home; }
Defining a Object method function PrintCard() {
line1 = "Name: "+ this.name + "<br>\n";
line2 = "Address: " + this.address + "<br>\n"; line3 = "Work Phone: " + this.workphone + "<br>\n"; line4 = "Home Phone: " + this.homephone + "<hr>\n"; document.write(line1, line2, line3, line4);
}
You now have a function that prints a card, but it isn't officially a method of the Card object. The last thing you need to do is make PrintCard() part of the function definition for Card objects. Here is the modified function definition:
function Card(name,address,work,home) { this.name = name; this.address = address; this.workphone = work; this.homephone = home; this.PrintCard = PrintCard; }
tom = new Card("Tom Jones", "123 Elm Street", "555-1234", "555-9876"); tom.PrintCard();
Extending Built-In Objects:
JavaScript includes a feature that enables you to extend the definitions of built-in objects. For example, if you think the String object doesn't quite fit your needs, you can extend it, adding a new property or method. This might be very useful if you were creating a large script that used many strings.
You can add both properties and methods to an existing object by using the prototype keyword. (A prototype is another name for an object's definition, or constructor function.) The prototype keyword enables you to change the definition of an object outside its constructor function.
As an example, let's add a method to the String object definition. You will create a method called heading, which converts a string into an HTML heading. The following statement defines a string called title:
title = "Fred's Home Page";
This statement would output the contents of the title string as an HTML level 1 heading:
document.write(title.heading(1));
Listing 6.4 adds a heading method to the String object definition that will display the string as a heading, and then displays three headings using the method.
Listing 6.4. Adding a Method to the String Object
<html>
<head><title>Test of heading method</title> </head>
<body>
<script LANGUAGE="JavaScript" type="text/javascript"> function addhead (level) {
html = "H" + level; text = this.toString(); start = "<" + html + ">"; stop = "</" + html + ">"; return start + text + stop; }
String.prototype.heading = addhead;
document.write ("This is a heading 1".heading(1)); document.write ("This is a heading 2".heading(2)); document.write ("This is a heading 3".heading(3)); </script>
</body> </html>
First, you define the addhead() function, which will serve as the new string method. It accepts a number to specify the heading level. The start and stop variables are used to store the HTML "begin header" and "end header" tags, such as <h1> and </h1>.
After the function is defined, use the prototype keyword to add it as a method of the String object. You can then use this method on any String object or, in fact, any JavaScript string. This is demonstrated by the last three statements, which display quoted text strings as level 1, 2, and 3 headers.
function Name(first,last) { this.first = first; this.last = last; }
You can add additional properties to an object you have created just by assigning them:
Fred.middle = "Clarence";
Properties you add this way apply only to that instance of the object, not to all objects of the type. A more permanent approach is to use the prototype keyword, which adds a property to an object's prototype (definition). This means that any future object of the type will include this property. You can include a default value:
Name.prototype.title = "Citizen";
Object Oriented Java Script
Prototype-based programming is a style of object-oriented programming in which classes are not present, and behavior reuse (known as inheritance in class-based languages) is accomplished through a process of decorating existing objects which serve as prototypes.
This model is also known as class-less, prototype-oriented or instance-based programming. Java Script Object oriented programming – Custom Object
The Class: JS is a prototype-based language which contains no class statement, such as is found in C++ or Java. Instead JS uses functions as classes. Defining a class is easy as defining a function. Function Person() { }
The Object (Class Instance) To create a new instance, use new operator. var p1 = new Person(); var p2 = new Person();
The constructor is called at the moment of instantiation.
The Property properties are variables contained in the class. Properties defined within a class is done by keyword this, which refers to the current object.
function Person(gender) { this.gender = gender; alert(‘Person instantiated’); }
var p1 = new Person(‘Male’); alert(‘Person 1 is a ‘ + p1.gender);
The Methods are functions and they are defined as functions. To define a method, assign a function to a named property of the class’s prototype property; the name that the function is assigned to is the name that the method is called by on the object.
Person.prototype.sayHello = function() { Alert(‘Hello method..’);
In JavaScript methods are regular function objects that are bound to a class/object as a property which means they can be invoked "out of the context". Consider the following example code:
function Person(gender) { this.gender = gender; } Person.prototype.sayGender = function() { alert(this.gender); };
var person1 = new Person('Male'); var genderTeller = person1.sayGender;
person1.sayGender(); // alerts 'Male' genderTeller(); // alerts undefined
alert(genderTeller === person1.sayGender); // alerts true
alert(genderTeller === Person.prototype.sayGender); // alerts true
This example demonstrates many concepts at once. It shows that there are no "per-object methods" in JavaScript since all references to the method point to the exact same function, the one we have defined in the first place on the prototype. JavaScript "binds" the current "object context" to the special "this" variable when a function is invoked as a method(or property to be exact) of an object. This is equal to calling the function object's "call" method as follows:
genderTeller.call(person1); //alerts 'Male'
Inheritance
Inheritance is a way to create a class as a specialized version of one or more classes (JavaScript only supports single class inheritance). The specialized class is commonly called the child, and the other class is commonly called the parent. In JavaScript you do this by assigning an instance of the parent class to the child class, and then specializing it. In modern browsers you can also use Object.create to implement inheritance.
JavaScript does not detect the child class prototype.constructor see Core JavaScript 1.5 Reference:Global Objects:Object:prototype property, so we must state that manually.
In the example below, we define the class Student as a child class of Person. Then we redefine the sayHello() method and add the sayGoodBye() method.
// define the Person Class function Person() {}
Person.prototype.walk = function(){ alert ('I am walking!');
};
Person.prototype.sayHello = function(){ alert ('hello');
};
function Student() {
// Call the parent constructor Person.call(this);
}
// inherit Person
Student.prototype = new Person();
// correct the constructor pointer because it points to Person Student.prototype.constructor = Student;
// replace the sayHello method
Student.prototype.sayHello = function(){ alert('hi, I am a student');
}
// add sayGoodBye method
Student.prototype.sayGoodBye = function(){ alert('goodBye');
}
var student1 = new Student(); student1.sayHello();
student1.walk();
student1.sayGoodBye();
// check inheritance
alert(student1 instanceof Person); // true alert(student1 instanceof Student); // true
Using Object.create the inheritance line would instead be:
AngularJS
AngularJS is a client-side JavaScript framework It's used to build web applications
It is prescriptive
Makes creating a user interface (UI) easier through data-binding It helps organize and architect an application
it has custom elements and attributes it uses dependency injection
What is AngularJS?
AngularJS is a framework that helps you build front-ends for web-based applications.
AngularJS is a prescriptive client-side JavaScript framework used to make single-page web apps.
Note:
Prescriptive Architecture vs. Descriptive Architecture
A system’s prescriptive architecture captures the design decisions made prior to the system’s construction. It is the as-conceived or as-intended architecture.
A system’s descriptive architecture describes how the system has been built. It is the as-implemented or as-realized architecture.
AngularJS is prescriptive in the sense that it has a recommended way of building web apps. It has its own spin on the ubiquitous Model View Controller (MVC) pattern that is especially well suited for JavaScript. In this way, Angular is prescribing a way for you to divide your application up into smaller parts.
AngularJS is a framework that runs in the web browser.
AngularJS is for single page apps, meaning the browser only loads the page once, but then makes asynchronous calls to the server to fetch new information. Here asynchronous means that the application can continue to function without having to stop and wait for the server to respond.
Core Features of AngularJS
Two-way Data Binding: Let's say you have a form to store user contact info and you want to update the addresses input box when data is returned from the server. You could do the following:
<span id="yourName"></span>
document.getElementById('yourName')[0].text = 'bob';
You manually seek to the element you want to change, calling a long, awkward series of DOM methods.
You also have to make this call every time something causes the address to change.
If we take the same example above and use data-binding we accomplish the same thing but faster. Here's our example with data-binding:
<span>{{yourName}}</span> var yourName = 'bob';
Model View Whatever (MVW): MVC is a pattern for dividing an application into
different parts (called Model, View, and Controller), each with distinct responsibilities.AngularJS as a "Model View Whatever" framework.
In AngularJS, the View is simply your HTML with the AngularJS syntax compiled into it. Once the initial compilation cycle completes, the View can then bind to the object which is essentially the ViewModel.
HTML Templates: HTML templates are useful when you want to predefine a layout with dynamic sections to be filled in it is connected with an appropriate data structure.
An example of this would be if you wanted to repeat the same DOM element over and over in a page such as a list or a table. You would define what you want a single row to look like and then attach a data structure, such as a JavaScript array, to it. The template would repeat each row for as many items in the array filling in each instance with the values of that current array item.
There are plenty of templating libraries out there but most of them require you learn a new syntax. AngularJS templates are HTML and are validated by the browser just like the rest of the HTML in the page.
Deep Linking:
Dependency Injection: Defined a function that accepts a parameter you have leveraged dependency injection. You are injecting something that your function depends on to complete its work.
Consider this code:
Defining functions without DI function a () { return 5; } function b () { return a() + 1; } console.log(b());
Defining functions with DI service('a', function () { return 5;
});
service('b', function (a) { return a() + 5;
service('main', function (b) { console.log(b());
});
Overriding with DI
// swap out 'b' easily by redefining it in another file: service('b', function (a) {
return 1; // this is a test value });
Directives: it allows you to extend HTML to do some really powerful things.
Directives provide the perfect way to merge the declarative nature of HTML and the functional nature of JavaScript into one place.
Let's say you're writing an application that has a dropdown. <div class="container">
<div class="inner"> <ul>
<li>Item
<div class="subsection">item 2</div> </li>
</ul> </div> </div>
You can use a directive to make a shortcut so you only have to type: <dropdown>
<item>Item 1
<subitem>Item 2</subitem> </item>
</dropdown>
TESTABLE: How do you REALLY know your app works? The answer is "by writing tests," but it's often more complicated than that.
AngularJS makes it easy to write unit tests.
Mocking out parts of your application, you can test each feature in isolation.
Angular also makes it easy to write integration tests that ensure your whole stack is functioning as expected.
A quick recap: AnguarJS has many benefits and features. If you are were to pick three things to remember about it, they are data-binding, testability, and "just JavaScript." Or consider the old way of writing web-apps with event handlers and DOM mutations, and think of how much easier it would make your development process to use Angular instead.
Hello Angular Example we're going to make a "Hello ___" program, where we have an input box that fills the blank in with whatever we type into the box.
<body ng-app="helloApp"> <div ng-controller="HelloCtrl"> <p>{{greeting}} {{person}}</p> <input ng-model="person"> </div> <script> angular.module('helloApp')
.controller('HelloCtrl', function ($scope) { $scope.greeting = 'Hello';
$scope.person = 'World'; });
</script> </body>
a Single Page Application is one in which we have a shell page and we can load multiple views into that.
So a traditional app, as you know you typically blink and load everything again. It’s not very efficient on the bandwidth, especially in the mobile world.
In a SPA we can load the initial content upfront and then the different views or the little kind of mini- web pages can be loaded on the fly and embedded into the shell.
The challenges with SPA: 1. DOM Manipulation 2. History 3. Module Loading 4. Routing 5. Caching 6. Object Modeling
7. Data Binding 8. AJAX / Promises 9. View Loading
Angular JS is a fully featured SPA Framework:
Data Binding, MVC, Routing, Testing, jqLite, Templates, History, Factories, ViewModel, Controllers, Views, Directives, Services, Dependency Injection, Validation
Getting Started with AngularJS 1. Download from angularjs.org
2. Import the angular.js file in your web page <script src=”angular.min.js”></script> Using Directives and Databinding Syntax: Directives start with ng i.e. ng-app, ng-model
ng-model does is behind the scenes it’s going to add a property up in the memory called “name” into what’s called “the scope”.
Include the ng-app Include the ng-model Bind to that model. <html ng-app>
<body>
Working with Model directive and Data Binding <input type="text" ng-model="name"/> {{name}} </body>
Working with Init and Repeat directive
We’ve now initialised our data with the ng-init.
We’re going to iterate through our data with the ng-repeat
We simply give it the name and it’s going to put that name into the variable when we bind to it <div ng-init="names=['Sarath', 'Chandu', 'Teju', 'Devi']">
<ul>
<li ng-repeat="myname in names">{{myname}}</li> </ul>
</div>
ng-init is used to initialize data to bind to and display.
ng-repeat which will simply loop through all the names, and then data-bind or apply the value into the <li>. For each myname in the names variable write out the myname. Myname is just a variable.
Try initializing data in body. i.e. <body ng-init=….>
Repeat with Objects: Instead of having array of strings, I have an array of objects.
<div ng-init="customers=[{name:'John Smith', city: 'Phoenix'}, {name:'John Doe', city: 'New York'}, {name:'Jane Doe', city: 'San Fransisco'}]">
<ul>
<li ng-repeat="cust in customers">{{cust.name}} - {{cust.city}}</li> </ul>
Filtering
let’s do a filter by and whenever they type a name instead of data-binding to it I want to use it as a filter. So we’re going to filter by the name property that’s in our model.
<div ng-init="customers=[{name:'John Smith', city: 'Phoenix'}, {name:'John Doe', city: 'New York'}, {name:'Jane Doe', city: 'San Fransisco'}]">
Enter Name: <input type="text" ng-model="name">{{name}} <ul>
<li ng-repeat="cust in customers | filter:name">{{cust.name}} - {{cust.city}}</li> </ul>
</div>
We can also use “orderBy”. do another pipe and “orderBy” and then in quotes give it the property. <li ng-repeat="cust in customers | filter:name | orderBy:'city'">{{cust.name}} - {{cust.city}}</li>
Let’s say we wanted the name to be uppercase and the city to be lowercase.
<li ng-repeat="cust in customers | filter:name | orderBy:'city'">{{cust.name | uppercase}} - {{cust.city | lowercase}}</li>
Views, Controllers and Scope
You should be able to define a controller that you can bind to different views. Maybe you have a mobile view, you have a desktop view or whatever it may be.
<div ng-controller="SimpleController"> <ul>
<li ng-repeat="cust in customers">{{cust.name + ' ' + cust.city}}</li> </ul>
</div>
<script>
function SimpleController($scope) { $scope.customers = [
{name: 'Dave Jones', city: 'Phoenix'}, {name:'Jamie Riley', city:'New York'}, {name: 'Heedy Wahlin', city: 'Atlanta'}, {name:'Thomas Winter', city: 'Seattle'} ]
} </script>
In the parameter signature. You’ll see that we pass $scope. This is dependency injection that’s built into AngularJS.
When this controller gets used, will automatically inject a scope object in. You’ll see that from there we’ll take that object and add in a property onto it called customers which is simply an array of object literals.
What this controller can do then is serve as the source of the data for the view but the controller again shouldn’t know anything about the view, so how would we possibly communicate customers over? Well that’s why we’re injecting scope. Scope is to be that view between the controller and the view.
If we come up to our view up here the scope gets injected and then that scope is going to be automatically bound into the view once the view knows about this controller.
When this [the controller] gets initialised the scope gets passed in but it’s initially empty.
Well we’re going to add a customers property. What’s going to happen then is this controller will be used by the view. The controller itself though isn’t going to be called – it’s going to go through the scope. The scope itself is implicitly available – in this case to the entire div: from the start of the div to the end of the div.
Now look at the ng-repeat here. It’s the same thing I did earlier in the demo, except in this case it’s binding to the scope’s customers property
What’s going to happen now is the view, because it knows about the controller, automatically gets passed the scope. Angular does that kind of behind the scenes – it just happens automatically. We’re going to then control in our view what properties we want to bind to. In this case we’re going to bind to the customers.
From here it’s standard data binding like we’ve seen earlier: we bind to the name and we bind to the city and we’re kind of off and running.
The first thing to talk about is although I created the controller in some previous demo’s right in the view that’s not the recommended way to do it.
Keep in mind you might actually have different views. You might have a mobile view, maybe one specific to iPad or Surface or something like that, and maybe have one for desktops. It’s very possible.
Just means “Heh! What’s the name of the module you’ve defined in JavaScript?” Creating a Module:
What exactly is the empty array for? This is where dependency injection comes in because your module might actually rely on other modules to get data.
We say “Heh Angular! Create me a module called demoApp.” I need to rely on another module. In this case I just called it helperModule. This would be some other JavaScript file that you might reference.
telling Angular “Go find that module. Go look it up wherever it is and inject it in and make it available to my controllers and directives and filters and factories and all that stuff that this particular module might have.
Creating a Controller in Module <html ng-app="demoApp">
<div ng-controller="SimpleController"> <ul>
<li ng-repeat="cust in customers">{{cust.name + ' ' + cust.city}}</li> </ul>
</div> <script>
var demoApp = angular.module('demoApp', []); var controllers = {};
controllers.SimpleController=function($scope) { $scope.customers = [
{name: 'Dave Jones', city: 'Phoenix'}, {name:'Jamie Riley', city:'New York'}, {name: 'Heedy Wahlin', city: 'Atlanta'}, {name:'Thomas Winter', city: 'Seattle'} ];
};
demoApp.controller(controllers); </script>
The Role of Routes
at some point if you’re building a single page application you’re going to need routes because we need to load different views into our shell page.
Defining Routes
Declarative markup
• ng:include Include HTML partials like cfinclude. • ng:repeat Loop over collections like cfloop.
• ng:show / ng:hide Show or hide nodes based on a condition. • ng:class Add or remove classes from nodes.
• ng:click / ng:change Handle user interactions with the page.
• Expressions {{user.name}}
Two way data binding
• Form controls <input name="echo"> {{echo}}
• Automatic evaluation <button ng:click="value = value + 1"> {{value}}
Model-View-Controller
<form ng:controller="ProfileController" ng:submit="save()"> <h2>Hello, {{user.name}}.</h2>
<p>You can edit your profile details below.</p> <label>Email <input name="user.email"></label>
<label>Address <textarea name="user.address"></textarea></label> <input type="submit" value="Save">
</form> <script>
function ProfileController() {
this.user = {name: 'Elliott', email: 'esprehn@gmail.com'}; this.save = function() {
// Ajax request to save the user };
};
</script>
Dependency Injection
• Automatic injection
function ProfileController($resource, activityService_) { ... }; • Explicit injection
function ProfileController(resource, activityService) { ... }; ProfileController.$inject = ['$resource', 'activityService'];
RESTful resources
• Like ORM for REST
• Supports caching, bulking and JSONP • Mocks provided for testing
<script>
// $resource is automatically injected by name. function ProfileController($resource) {
var Users = $resource('/users/me'); this.user = Users.get(); this.save = function() { Users.save(this.user); }; }; </script>
Service abstraction
• Define services for use in your controllers • Easily swapped out for testing
angular.service('profileService', function($resource) { return $resource('profiles/:id'); }); function ProfileController(profileService_) { // ... });
Create your own custom tags widgets
• Define your own widgets<app:ProfileEditor profile="user"> </app:ProfileEditor>
• Reusable Components
<jqui:Button icon="ui-icon-gear">Click Me</jqui:Button> • Attributes
<input name="tags" jqui:autocomplete="tagList">
Testability
• No DOM manipulation in controllers • Mocks provided for XHR
• Easily mock out services • Angular services are not special • JsTD and Jasmine integration
End-to-End Runner
<script>
describe('ProfileController', function() { it('should save profiles', function() { browser().navigateTo('/profiles/mine'); expect(element('h2').text()).toEqual('Hello, Elliott.'); input('firstname').enter('Ethan'); element('#save').click(); browser().reload(); expect(element('h2').text()).toEqual('Hello, Ethan.'); }); }); </script>
End-to-End DSL
<script> describe('ProfileController', function() { it('should save profiles', function() { browser().navigateTo('/profiles/mine'); expect(profilePage().greeting()). toEqual('Hello, Elliott.');profilePage().save(); browser().reload(); expect(profilePage().greeting()). toEqual('Hello, Ethan.'); }); }); </script>
Good example dealing with DOM. Here we will change style of an html tag by binding its style property to a model. <!doctype html> <html > <head> <script src="angular.min.js"></script> <style type="text/css"> .style1{ border:1px #333 solid; width:300px; } .style2{ border:1px #999999; background-color:#0099FF; color:#fff; width:300px; } </style> </head> <body> <div ng-app>
<input type="text" ng-model="data.source" > <h2 class="{{data.source}}">Hello AngularJS</h2> </div> </body> </html> Modules
var firstModule = angular.module("firstModule", []);
Now we will add controller to this module, notice what has been changed from the way we defined the controller above.
var firstModule = angular.module("firstModule",[]);
firstModule.controller("FruitController", function ($scope){
$scope.fruits=['Apple','Banana','Watermelon','Peach']; });
Still our app does not know about our module, to use our module we need to define to our ng-app
<html ng-app="firstModule">
Simple AngularJS
http://stephanebegaudeau.tumblr.com/Expressions: In order to create the views of your application, AngularJS let you execute expressions directly within your HTML pages.
<!DOCTYPE HTML> <html ng-app> <head> <script src="angular.min.js"></script> </head> <body> <div>1+1 = {{1+1}}</div> </body> </html> Scope
The scope is used to link the controllers and the views to which they are binded. A controller can add data and function in its scope and then they will be accessible in the view. In our case, we have used in the view a variable named “users” which was created in the scope by the controller “UsersCtrl”.
Partial Views
AngularJS is very good to build single page web applications. For those who are not familiar with this concept, it consists on a web application where you only have one “real” HTML page whose content can be changed in Javascript without having to download a new page. The new content is created programmatically in Javascript of with the use of templates. Those applications have advantages like performances (since you are not downloading a new HTML page each time you are navigating to a new page) and drawbacks like history management (what happens if your users click on the button back of their browser?).
With AngularJS, you see that you are using a framework created by people who know what they are doing, as a result most of the problems of regular single page web applications are handled by AngularJS itself.
In order to build your application, You define a main page (index.html) which acts as a container for your web application. In this page, you can bind part of your application to a specific AngularJS module with the directive “ngApp”. You can bind the whole page to a single AngularJS module if you want. After that, you can use the directive “ngView" in order to use partial views.
Your module will tell AngularJS which view should be display in the “ngView” element. This directive also let you separate the content of your application in dedicated files.
Code Organization in Large AngularJS and JavaScript Applications
Modularity
Hopefully the trite metaphors haven't been too tedious but here's the recap:
Your significant other is the new developer on the team who's been asked to fix a bug on one of the many screens in your app.
The developer sifts through the directory structure and sees all the controllers, models and services neatly organized. Unfortunately it tells him/her nothing about which objects are related or have dependencies on one another.
If at some point the developer wants to reuse some of the code, they need to collect files from a bunch of different folders and will invariably forget code from another folder somewhere else.
Believe it or not, you rarely have a need to reuse all of the controllers from the e-commerce app in the new reporting app you're building. You may however have a need to reuse some of the authentication logic. Wouldn't it be nice if that was all in one place? Let's reorganize the app based on functional areas:
cart/
CartModel.js CartService.js common/
directives.js filters.js product/ search/ o SearchResultsController.js o SearchResultsModel.js ProductDetailController.js ProductModel.js ProductService.js user/ LoginController.js RegistrationController.js UserModel.js UserService.js
Any random developer can now open the top-level folder and immediately gain insight into what the
application does. Objects in the same folder have a relationship and some will have dependencies on others.
Understanding how the login and registration process work is as easy as browsing the files in that folder. Primitive reuse via copy/paste can at least be accomplished by copying the folder into another project.
With AngularJS we can take this a step further and create a module of this related code:
var userModule = angular.module('userModule',[]);
userModule.factory('userService', ['$http', function($http) { return new UserService($http);
}]);
userModule.factory('userModel', ['userService', function(userService) { return new UserModel(userService);
}]);
userModule.controller('loginController', ['$scope', 'userModel', LoginController]);
userModule.controller('registrationController', ['$scope', 'userModel', RegistrationController]); http://viralpatel.net/blogs/angularjs-introduction-hello-world-tutorial/ <!DOCTYPE html> <html ng-app> <head>
<title>Hello World, AngularJS - ViralPatel.net</title> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js "></script> </head> <body>
Write some text in textbox:
<input type="text" ng-model="sometext" /> <h1>Hello {{ sometext }}</h1> </body> </html>
ng-app
First thing that we notice is an attribute ng-app within <html> tag. This attribute tells the Angular to be active in this portion of the page. So in our case entire document. If you want to enable Angular only at specific location in your webpage then you can define ng-app attribute to any DIV or other tag.
ng-model and Two way data binding
We define attribute ng-model in textbox as ng-model=”sometext”. ng-model binds the state of textbox with model value. In our case we define a model sometext. This model value is bound with the value of textbox using ng-model attribute. Thus when the textbox value changes,
Angular automatically changes the model sometext with this value. This is called Two way data binding. Similarly, if we change the model value than Angular will change the value of textbox. Two way data binding is the core of Angular‟s magical spell. It just works. You‟ll get to know about it more once we start adding complexity in our application.
AngularJS two-way data binding is its most notable feature and reduces the amount of code written by relieving the server backend from templating responsibilities.
{{ sometext }}
Note how we wrap our model value in double curly braces. This tell Angular to bind the value of modelsometext in place of {{ sometext }}.
ng-show / ng-hide
Now lets further modify our demo and add one more Angular attribute ng-show. In below code, we added attribute ng-show=”sometext” to <h1> tag.
<!DOCTYPE html> <html ng-app> <head>
<title>Hello World, AngularJS - ViralPatel.net</title> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js "></script> </head> <body>
Write some text in textbox:
<input type="text" ng-model="sometext" />
<h1 ng-show="sometext">Hello {{ sometext }}</h1>
</body> </html>
Filter uppercase and lowercase
As its name suggest, this filter convert the expression into uppercase letters. Lets check a quick demo. Lets modify few lines from our above example and use uppercase filter.
<!DOCTYPE html>
<htmlng-app>
<head>
<title>Hello World, AngularJS - ViralPatel.net</title> <scripttype="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> </head> <body>
Write some text in textbox:
<inputtype="text"ng-model="sometext"/>
<h1>Hello {{ sometext }}</h1>
<h4>Uppercase: {{ sometext | uppercase }}</h4> <h4>Lowercase: {{ sometext | lowercase }}</h4>
</body>
</html>
1. What are Scopes?
Before we get into Controllers let us understand Scopes. Scope is nothing but an object that Glues the View with Controller. They hold the Model data that we need to pass to view. Scope uses Angular‟s two-way data binding to bind model data to view.
Imaging $scope as an object that links Controller to the View. It is controllers responsibility to initialize the data that the view needs to display. This is done by making changes to $scope. Let us see a small Hello World application to understand $scope.
<!DOCTYPE html>
<htmlng-app>
<head>
<title>Hello World, AngularJS - ViralPatel.net</title>
<scripttype="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> </head>
<body>
<divng-controller="ContactController">
Email:<inputtype="text"ng-model="newcontact"/> <buttonng-click="add()">Add</button>
<h2>Contacts</h2>
<ul>
<ling-repeat="contact in contacts"> {{ contact }} </li> </ul>
</div>
<scripttype="text/javascript">
function ContactController($scope) {
$scope.contacts = ["hi@email.com", "hello@email.com"];
$scope.add = function() { $scope.contacts.push($scope.newcontact); $scope.newcontact = ""; } } </script> </body> </html>
1.2. ng-controller
This attribute defines a Controller to be bound with the view. In this case we defined a controller called ContactController in DIV using ng-controller attribute. Thus whatever we put inside that DIV, the ContactController will have its influence on it.
ContactController is nothing but a plain vanilla JavaScript function. In the demo we defined it as function. Also see the definition of ContactController function. There is an object $scope which we pass as an argument. This object is used to bind the controller with view. When AngularJS initialize this controller, it automatically creates and injects the $scope object to this function using dependency injection (More on dependency injection in coming tutorials). For now just note that the $scope object is created by Angular and injected in this controller function.
2. Initial state of a scope object
Typically, when you create an application you need to set up an initial state for an Angular scope. In our case we need initial state to be list of contacts.
On $scope object, we defined an array called contacts:
When Angular initilize this function (ContactController), it automatically creates this array and binds it in$scope object. Then in our view we display the array using ng-repeat attribyte. Thus, $scope provides us with a way to pass/retrieve objects from Controller to View and vice-versa.
2.1. ng-click
It is also possible to define functions on $scope and use the same in View. In our demo, we created a function add() on $scope and use it on Add button click:
$scope.add = function() {
... }
The function add() is bound to Add button using an attribute ng-click. ng-click binds the click event on the button or link or any clickable element with the function that is defined within $scope. So in this case, whenever Add button is clicked, the add() method on $scope will be called.
In add() method we add (or push) a string in contacts array. This is the string that user types in textbox. Note that we bind textbox using ng-model attribute.
<input type="text" ng-model="contact" ...
This textbox‟s value we got in $scope.contact as we bind it using ng-model attribute. Pretty nice, isn‟t it!!
3. How to define a Controller
So we got some basic idea of what Controllers are. Just plain vanilla JavaScript functions that we add in an Angular application to add some business logic and bind the view with model.
In the above demo, we defined controller as JavaScript function. While this is the easiest way to define them, but is certainly not advisable one. If your application grows, soon you‟ll have bunch of controllers lying here and there in code poluting the JavaScript namespace.
So instead of defining controller as:
functionContactController($scope) {
//...
}
3.1. AngularJS Modules
So what-the-heck are modules? Well, modules are the logical entities that you divide you app in. So your app can contain several modules (like Transaction, Report, etc.). Each module represent a logical entity within the app.
Furthermore, each modules have several Controllers. As referred in above diagram, a module can contain one or more controllers and views. We haven‟t touch based on Views. We will see how each module can be linked with view using Routing in AngularJS in our next tutorial. For now just assume that each controller has one or more views linked to it.
So in this case, we can add one or more controllers to a module. Let us check the syntax to create a module and add controller to it:
varmyApp = angular.module('myApp',[]);
myApp.controller('ContactController', ['$scope', function($scope) {
$scope.contacts = ["hi@email.com", "hello@email.com"];
$scope.add = function() {
$scope.contact = ""; }
}]);
In above example we created a module called myApp using angular.module() method. Then we added a controller ContactController to this module. This is just an alternate way of defining a controller but recommended one.
Notice how controller is declared using myApp.controller() method. We passed an array to this method. First argument of array is string „$scope‟ and next is the function itself that
representContactController. We explicitly told Angular that we have one argument (dependency) to our ContactController which is $scope. This is useful when you Minify or
obfuscate JavaScript for production release. In that case the argument $scope might be renamed to $s, but because we defined string „$scope‟ as first argument, Angular is aware that first
dependency to this controller is $scope object.
To cut it short, always stick to the above way of defining controllers.
4. Nested Controllers
We can declare the scope of controller in our HTML page using ng-controller attribute. For example:
<divng-controller="CarController">
... </div>
We can declare number of controllers and nest them within each other. For example: <div ng-controller="CarController">
My name is {{ name }} and I am a {{ type }}
<div ng-controller="BMWController">
My name is {{ name }} and I am a {{ type }}
<div ng-controller="BMWMotorcycleController"> My name is {{ name }} and I am a {{ type }}
</div> </div> <script> functionCarController($scope) { $scope.name = 'Car'; $scope.type = 'Car'; } functionBMWController($scope) { $scope.name = 'BMW'; } functionBMWMotorcycleController($scope) { $scope.name = 'BMWMotorade'; $scope.type = 'Motorcycle'; } </script>
4.1. Online Demo
In above demo, notice how each nested Controller‟s scope override the scope of parents controller. First we defined a controller CarController which defines two
variables name and type within scope. NextBMWController is nested within CarController using ng-controller attribute. BMWController overridesname attribute and change it to BMW. It does not change type attribute so type attribute is still Car.
BMWMotorcycleController is the inner-most controller defined within controllers hierarchy. It overrides both name and type attribute of scope.
This way you can nest one controller within another and take advantage of parent controllers attributes whenever needed.
5. Inheritance in Controllers
In order to take advantage of inheritance of scope in Nested controllers, one has to define Controllers one into another using ng-controller attribute. Sometimes you don‟t want to define controllers like this but still want to use power of inheritance within controllers. May be you want to put common logic into BaseController and use it in all the child controllers.
In order to achieve this, we must use $injector object that AngularJS provides. <div ng-controller="BMWController">
My name is {{ name }} and I am a {{ type }}
<button ng-click="clickme()">Click Me</button>
</div> <script> functionCarController($scope) { $scope.name = 'Car'; $scope.type = 'Car'; $scope.clickme = function() {
alert('This is parent controller "CarController" calling'); }
}
functionBMWController($scope, $injector) {
$injector.invoke(CarController, this, {$scope: $scope});
$scope.name = 'BMW'; } </script>
5.1. Online Demo
Play on JSFiddle – http://jsfiddle.net/viralpatel/WCZcZ/
We define two controllers, CarController an BMWController. CarController defines two attributes name and type on $scope and also defines one method clickme().
BMWController just override name attribute. Notice that it does not have name and clickme defined within its body. These attributes are defined by parent controller in this case
CarController. Within BMWController, we initialize CarController and bind it into current scope using $injector.invoke() method.
Once this is done, notice how in HTML page the BMWController points to its parent‟s attributes.
6. End to end application using AngularJS
Controller
Let us apply the knowledge that we acquired so far and create a ContactManager application. Following are some basic requirements of this application:
1. User can add new contact (name, email address and phone number) 2. List of contacts should be shown
4. User can edit any contact from contact list
Following is the HTML code which defines a FORM to save new contact and edit contact. And also it defines a table where contacts can be viewed.
6.1. The HTML
<divng-controller="ContactController">
<form>
<label>Name</label>
<inputtype="text"name="name"ng-model="newcontact.name"/> <label>Email</label>
<inputtype="text"name="email"ng-model="newcontact.email"/> <label>Phone</label>
<inputtype="text"name="phone"ng-model="newcontact.phone"/> <br/>
<inputtype="hidden"ng-model="newcontact.id"/>
<inputtype="button"value="Save"ng-click="saveContact()"/> </form> <table> <thead> <tr> <th>Name</th> <th>Email</th> <th>Phone</th> <th>Action</th> </tr> </thead> <tbody> <trng-repeat="contact in contacts"> <td>{{ contact.name }}</td> <td>{{ contact.email }}</td> <td>{{ contact.phone }}</td>
<td>
<a href="#"ng-click="edit(contact.id)">edit</a> | <ahref="#"ng-click="delete(contact.id)">delete</a> </td>
</tr>
</tbody>
</table>
</div>
Just note that we have used ng-model, ng-click and ng-repeat attributes from Angular so far.
To add life to this application, we add following JavaScript code.
6.2. The JavaScript
varuid = 1; functionContactController($scope) { $scope.contacts = [{ id:0, 'name': 'Viral', 'email':'hello@gmail.com', 'phone': '123-2343-44' } ]; $scope.saveContact = function() { if($scope.newcontact.id == null) {
//if this is new contact, add it in contacts array $scope.newcontact.id = uid++;
} else{
//for existing contact, find this contact using id //and update it.
for(i in$scope.contacts) { if($scope.contacts[i].id == $scope.newcontact.id) { $scope.contacts[i] = $scope.newcontact; } } }
//clear the add contact form $scope.newcontact = {}; } $scope.delete= function(id) {
//search contact with given id and delete it for(i in$scope.contacts) { if($scope.contacts[i].id == id) { $scope.contacts.splice(i,1); $scope.newcontact = {}; } } } $scope.edit = function(id) {
//search contact with given id and update it for(i in$scope.contacts) {
if($scope.contacts[i].id == id) {
//we use angular.copy() method to create //copy of originial object
$scope.newcontact = angular.copy($scope.contacts[i]); }
} } }
First thing to note, we created a variable uid and set its initial value to 1. This variable is used to generate unique ids for each new contact we save. In real life application you may want to do this at backend.
We defined one controller ContactController. This controller defines following objects within $scope:
Scope object Type Comment
$scope.contacts Array
Array to store contact objects. In real life app, this should be maintained at server side.
$scope.saveContact
JavaScript Function
Saves the newcontact object within contacts array. Check if contact is new or is being updated
$scope.delete
JavaScript Function
Delete the contact object from contacts list based on id specified
$scope.edit
JavaScript
6.3. Online Demo
Play on JSFiddle – http://jsfiddle.net/viralpatel/JFYLH/
You can add new contact using the above form. Once new contact is saved, the list showing contacts will be updated. Each contact can be edited and deleted. You got the gist
Building a simple single page application using
AngularJS
I am going to walk you through building a SPA (single page application) usingAngularJS, Google's latest JavaScript MVC framework. After developing applications
using Backbone.js, Spine.js and good ol' jQuery I fell in love with AngularJS. It makes development of SPAs actually fun removing a lot of the boilerplate that most of the other frameworks make you write to get a simple app started.
The app we are going to build today is a simple multipage website that will read data in from a static JSON file. We will be covering setting up AngularJS, routing, rendering partials, communication between controllers and loading JSON asynchronously.
Download the source code View the demo
Sections
Setting up AngularJS
Routing
Rendering partials
Loading JSON
Communicating between controllers
Before we get started it's a good idea to watch the intro videos on angularjs.org as they cover most of the basics. I'm going to assume that you understand the concepts of how the controller binds $scope with the views and how the ng-modeldirective works.
Setting up AngularJS
This tutorial will require you to run these files via a web server. If you have
apache/MAMP/WAMP set up you should be able to create a new directory under your webroot and access via localhost. I like to run the npm module nws which creates a web server in the current directory allowing me to get started quickly.
Html
The first thing you will want to do is setup your module. You do this by adding the ng-app attribute to your html tag. In the case of our application we will call our module Site.
<html lang="en-US" ng-app="Site">
The next thing we want to do is set up a controller. The controller is bound to the
element you add it to and it's children. We are going to add an AppController to our body tag which allows the entire body to inherit from this controller. To add a controller you use the ng-controller attribute.
<body ng-controller="AppController">
Here is a template including AngularJS from CDNJS that I will be using throughout this
tutorial. JavaScript
Now that our html is set up we need to create the module and controller in our/js/site.js file that is included.
var Site = angular.module('Site', []);
function AppController ($scope) {
}
The first line creates our Site module and the function defines our AppController. The controller receives one argument (at the moment) $scope which binds models between the view (html) and controller.
Routing
If you took a look at the template above you will have noticed that there are three links in the nav bar: Home, About and Contact. We want to be able to route to these links and load a section from the JSON file based on the slug.
The first thing we need to do is configure our Site module to use the $routeProviderand then set up our routes.
Site.config(function ($routeProvider) { $routeProvider
.when('/page/:slug', {templateUrl: 'partials/page.html', controller: 'RouteController'})
.otherwise({redirectTo: '/page/home'}); });
We are passing in an anonymous function to the modules config method. In the function we are passing in Angular's $routeProvider service which allows us to define routes. The two methods we are using are when() which takes a path and hash of options including the templatePath and controller and otherwise() which allows us to redirect to a route if one is not found.
We are defining one route for this application /page/:slug. This path contains
the:slug parameter, we can use this later using the $routeParams service to extract the page data from the JSON.
We are also setting a controller for this route (RouteController). This controller is in charge of binding the page content to the view.
function RouteController ($scope, $routeParams) {
// Getting the slug from $routeParams var slug = $routeParams.slug;
// We need to get the page data from the JSON // $scope.page = ?;
}
Now when you try and visit the page you should be redirected to /#/home and if you try and type in anything else it will redirect you back.
Rendering Partials
When we defined our route we set a templateUrl. This points to a static html file that contains 2 simple expressions containing properties that will be bound to the
RouteController's $scope.
<!-- partials/page.html --> <h1>{{page.title}}</h1> {{page.content}}
To include this partial into your layout you need to use the <ng-view></ng-view>directive. This will automatically be replaced with the partial set in the routes. You can see that this is included already in the template provided above.
Loading JSON
Let's load some data into this application. I've created a simple static JSON data store (in real life this would probably be generated by an API) which we will load in via Ajax when the application starts.
// pages.json {
"home": {
"title": "Home",
"content": "This is the home page. Welcome" },
"about": {
"title": "About",
"content": "This is the about page. Welcome" },
"contact": {
"content": "This is the contact page. Welcome" }
}
We should only load the JSON file once, cache it to a variable and access the variable when we need the data. Let's use Angular's $http service to grab the JSON file. To use the $http service we will need to pass it as an argument to theAppController.
function AppController ($scope, $rootScope, $http) {
// Load pages on startup
$http.get('/pages.json').success(function (data) { $rootScope.pages = data;
}); }
We are also passing in $rootScope which all scopes inherit from. We do this so this so that we can access the pages JSON data in our RouteController. We can then access the page data by using the slug we captured earlier and bind it to the scope so it's accessible in our partial.
function RouteController ($scope, $rootScope, $routeParams) {
// Getting the slug from $routeParams var slug = $routeParams.slug;
$scope.page = $rootScope.pages[slug]; }
Communicating between controllers
We've already demonstrated one way to communicate between controllers using
the $rootScope. Another option is using events. In Angular you can emit events and listen to events in different controllers while passing data from the emitter to the listener.
We want to pass the slug from the RouteController to the AppController so that we can set the active class on the current menu link. Angular has a ng-class directive which allows you to add conditional classes to elements.
<li ng-class="{active: slug == 'home'}"><a href="/#/page/home">Home</a></li> <li ng-class="{active: slug == 'about'}"><a href="/#/page/about">About</a></li>
<li ng-class="{active: slug == 'contact'}"><a href="/#/page/contact">Contact</a></li>
You can see that the RouteController is emitting the slug and the AppController is listening for the slug which then sets it onto it's scope and exposes it to the view.
function AppController ($scope, $rootScope, $http) {
// Load pages on startup
$http.get('/pages.json').success(function (data) { $rootScope.pages = data;
});
// Set the slug for menu active class
$scope.$on('routeLoaded', function (event, args) { $scope.slug = args.slug;
}); }
function RouteController ($scope, $rootScope, $routeParams) {
// Getting the slug from $routeParams var slug = $routeParams.slug;
$scope.$emit('routeLoaded', {slug: slug}); $scope.page = $rootScope.pages[slug]; }
I hope you guys enjoyed this walkthrough. I will be writing more about AngularJS in the future. If you guys have any questions about this post or have any topics you are interested in let me know in the comments.
Angular JS Concepts Overview
1. <!doctype html> 2. <html ng-app> 3. <head> 4. <script src="http://code.angularjs.org/1.0.6/angular.min.js"></script> 5. </head> 6. <body>
7. <p ng-init=" name='World' ">Hello {{name}}!</p>
8. </body>
1. The browser loads the HTML and parses it into a DOM 2. The browser loads angular.js script
3. Angular waits for DOMContentLoaded event
4. Angular looks for ng-appdirective, which designates the application boundary
5. The Module specified in ng-app (if any) is used to configure the $injector
6. The $injector is used to create the $compileservice as well as $rootScope
7. The $compile service is used to compile the DOM and link it with $rootScope
8. The ng-initdirective assigns World to thename property on the scope
9. The {{name}}interpolates the expression toHello World!
Scope
The scope is responsible for detecting changes to the model section and provides the execution
context for expressions. The scopes are nested in a hierarchical structure which closely follow the DOM structure. (See individual directive documentation to see which directives cause a creation of new scopes.)
The following example demonstrates how the nameexpression will evaluate into a different value depending on which scope it is evaluated in. The example is followed by a diagram depicting the scope boundaries. 1. <!doctype html> 2. <html ng-app> 3. <head> 4. <script src="http://code.angularjs.org/1.0.6/angular.min.js"></script> 5. <script src="script.js"></script> 6. </head> 7. <body>
8. <div ng-controller="GreetCtrl">
9. Hello {{name}}!