An interactive introduction to

AngularJS

What is AngularJS?

AngularJS is a structural framework for dynamic web apps, using HTML for templating and allows extending HTML's syntax to render custom built components.

Angular is what HTML would have been, had it been designed for applications

AngularJS is a front-end web application MVC framework

MVC - Model View Controller

Athough, Angular does behave a lot like MVVM - Model View ViewModel

AngularJS great for building SPAs

AngularJS splits up responsibilities into modules

Which makes it very testable

Unit Tests

  • karma
  • jasmine

E2E Tests

  • protractor

What does

AngularJS provide? 

Models

  • A Model  is a singleton defined by service
  • Handles the business logic
  • Model provides an excellent way to separate data and display
  • are great for unit testing!

Templating

AngularJS uses HTML for templating

You can choose to use other engines like jade

( VIEW )

Controller

  • Acts as an interlayer between model and view, should be as thin as possible.

  • avoid business logic in controller

  • should not care about presentation or DOM manipulation.

Two Way Data Binding

Through scope

"Providers"

  • Value
  • Constant
  • Factory
  • Service
  • Provider

Directives

Directives are special markers on a DOM element (such as an attribute, element name, comment or CSS class) that signals AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children

This deserves it's own presentation

Animations

Modules

AngularJS modules are collections of configuration and run blocks which get applied to the application during the bootstrap process

are containers for the different parts of your app

Routing

define routes, the view and controller that render when accessing that route

Let's make an app!

Create a static server

  1. Create a package json file
  2. install the express module
  3. create a server.js file
  4. setup express static middleware
    to serve static files from public/
  5. commit
  6. tag as step1_server
  1. Make a new angular_tutorial git project
  2. create a public/ directory
  3. add html5 markup to index.html
  4. import angular from cdnjs
  5. start the server with nodemon
  6. test
  7. commit
  8. tag as step2_html5

HTML5 Angular App

Templating

using angular binding tags, display a javascript expression on the page

  1. Set the body tag as the app container using the ng-app directive
  2. Concatenate a string in h1: "Hello"+"Angular!"
  3. Add 2 + 3 in a div
  4. test
  5. commit
  6. tag as step3_templating

Templating

Code Samples

<!-- angular model binding -->
<div>
  {{ "Hello"+"Angular!" }}
</div>

<!-- accepts any expression -->
<div>
  {{ 2 + 3 }}
</div>

Models

  1. Create a text input and set the model name to "myModel" using the ng-model directive

Use the ng-model directive to declare a model

Models

Code Samples

<!-- set firstName model in html template -->
<input type="text" ng-model="firstName">

<!-- bind model value to template -->
<div>
  {{ firstName }}
</div>

// set model in a controller
$scope.firstName = "Archer";

Two way data-binding

  1. Add the value of "myModel" to a new div
  2. test
  3. commit
  4. tag as step4_two_way_databinding

Using data binding tags, display the current value of myModel

Modules

  1. Set the value of the ng-app directive to "myApp" 
  2. Create "js/myApp.js" and import the source file
  3. commit
  4. tag as step5_angular_module

Import a new external javascript file.

Create a new angular module, and set the body tag as the module container.

Modules

Code Samples

// creation uses a 2nd array argument to import dependencies
angular.module('myApp', []);

// retrieval has only one argument
var myApp = angular.module('myApp');

myApp
    .config(function(){
        // config
    })
    .run(function(){
        // initialize
    });

Controller

  1. Declare myController in myApp.js
  2. Inject the $scope dependency
  3. Attach a new model named myFirstName to $scope with your name as the value
  4. Add a new div and set the ng-controller directive to myController
  5. test
  6. commit
  7. tag as step6_controller

declare a controller named myController

on the myApp module

Controller

Code Samples

var myApp = angular.module('myApp');

myApp.controller('MyController', function(){

});

myApp.controller('MyController', ['$scope', function($scope){

});

$scope

  1. Move the text input and {{ myModel }} into the controller
  2. Set the model named myModel to $scope with an initial value of "Ready Player One"
  3. test
  4. commit
  5. tag as step7_scope

set the initial value of myModel in the controller

Move Controller 

  1. Create and import "js/controllers.js"
  2. Access the myApp module in controllers.js
  3. Move myController to controllers.js
  4. test
  5. commit
  6. tag as step8_external_controller

move the controller into a separate file

Value

  1. Create and import "js/values.js"
  2. Access the myApp module in values.js
  3. Declare a Value named mainCharacter
    set to "Archer"
  4. Inject mainCharacter into myController
  5. add mainCharacter to the $scope and display it 
  6. test
  7. commit
  8. tag as step9_value

Create an injectable Value

Value

Code Samples

myApp.value('mainCharacter', 'Archer');

Constant

  1. Create and import "js/constants.js"
  2. Access the myApp module in constants.js
  3. Declare a Constant named APP_VERSION
    set to "v.0.1.0"
  4. Inject APP_VERSION into the run method of myApp
  5. add APP_VERSION to the $rootScope and display it 
  6. test
  7. commit
  8. tag as step10_constant

Create an injectable Constant

Constant

code samples

myApp.constant('APP_VERSION','v.0.1.0');

Factory

  1. Create and import "js/factories.js"
  2. Access the myApp module in factories.js
  3. Declare a Factory named CharacterVersionFactory
    that injects mainCharacter and APP_VERSION
    and returns the concatenated value
  4. Inject CharacterVersionFactory into myController
  5. Attach the factory to the $scope and display it
  6. test
  7. commit
  8. tag as step11_factory

Create an injectable Factory

like a Value, except can use other services

Factory

Code Samples

myApp.factory('HelloWorldFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!";
        },
        sayGoodbye: function() {
            return "Goodbye";
        }
    };
});

// inject in controller
function MyController($scope, HelloWorldFactory) {
    $scope.greeting = HelloWorldFactory.sayHello();
}

Service

  1. Create and import "js/services.js"
  2. Access the myApp module in services.js
  3. Declare a Service named BookService
    define a private array named books with data
    and declare two methods, getBooks and getBook
  4. Inject BookService into myController
  5. Attach books to $scope and display it
  6. test
  7. commit
  8. tag as step12_service

Create an injectable Service

like a Factory, except returns a service by invoking a constructor

Service

Code Samples

myApp.service('HelloWorldService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});


function HelloWorld2() {
    this.sayHello = function() {
        return "Hello, World!"
    };
}
myApp.service('HelloWorld2Service', HelloWorld2);


function HelloWorld3withDeps( $http ) {
    this.sayHello = function() {
        return "Hello, World!"
    };
}
myApp.service('HelloWorld3withDeps', ['$http', HelloWorld3withDeps]);

ng-repeat

  1. Convert the div.books into a ul tag
  2. Add the ng-repeat directive to iterate over books
  3. Add li.book>h4.book_title and li.book>p.book_author
  4. test
  5. commit
  6. tag as step13_ngRepeat

Use the ng-repeat directive to render each book

ng-repeat

Code Samples

<div ng-repeat="n in [42, 43, 44, 45]">
  {{n}}
</div>

<div ng-repeat="book in books">
  <h4>{{ book.title }}</h4>
  <p class="book_author">{{ book.author }}</p>
</div>

<div ng-repeat="movie in MovieService.getMovies()">
  <p>{{ movie.title }}</p>
</div>

ng-click

  1. Make books a public property, refactor
  2. Add an addBook method to BookService
  3. Instantiate a new literal from the book that's passed in
  4. Refactor myController to bind $scope.BookService
  5. Refactor the view to use BookService.books
  6. Create a form, a button, and add the ng-click directive
  7. Clear the new_book model after adding it
  8. test, commit
  9. tag as step14_ngClick

Use the BookService to add a new book

ng-click

Code Samples

<button type="button" ng-click="alert('hello world);">Hello World</button>

<button type="button" ng-click="BookService.addBook(new_book);">Add Book</button>

Provider

  1. Create a new server api/ endpoint that returns movies
  2. Create and import "js/providers.js"
  3. Access the myApp module in providers.js
  4. Create a new provider named Movies
  5. Configure the endpoint url in myApp config
  6. $scope.Movies -> Movies provider in myController
  7. Display all movies in the view
  8. test
  9. commit
  10. tag as step15_provider

Create an injectable and configurable Provider

It is the most verbose with the most abilities, but for most services it's overkill.

test!

sanity check!

Provider

Code Samples

myApp.provider('HelloWorld', function() {
    this.name = 'Stranger';
    this.setName = function(name) {
        this.name = name;
    };
    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!";
            }
        }
    };
});


// configurable, note 'HelloWorldProvider' in config
myApp.config(function(HelloWorldProvider){
    HelloWorldProvider.setName('Angular World');
});


// inject in controller
function myController($scope, HelloWorld) {
    $scope.greeting = HelloWorld.sayHello();
}

Filters

  1. Apply a filter to the movies expression in ul.movies
  2. display only movies released in 1983
  3. test
  4. commit
  5. tag as step16_basic_filter

Filter only movies released in 1983

Custom Filters

  1. Create and import "js/filters.js"
  2. Access the myApp module in filters.js
  3. Apply a filter named beforeYearFilter to the movies expression in ul.movies
    display only movies made after 1983
  4. test
  5. commit
  6. tag as step17_custom_filter

Create a custom Filter for movies released after 1983

Model Bound Filters

  1. Apply a filter to the books expression in ul.books
  2. display only books that match a user inputted title
  3. Add a new input[ng-model="searchBookTitle"]
  4. Bind the ng-filter value to searchBookTitle
  5. test
  6. commit
  7. tag as step18_model_bound_filters

Create a Filter that's matches user input to book titles

Filters

Code Samples

<ul class="books" ng-repeat="book in books | filter:year=1983">

<ul class="books" ng-repeat="book in books | filter:searchBookTitle">

Ordering Filters

  1. Apply an additional filter to the books expression to sort by title
  2. test
  3. Apply an additional filter to the movies expression to sort by year in reverse order
  4. test
  5. commit
  6. tag as step19_orderBy

Order book's by title, and reverse order movies by release date

Ordering Filters

Code Samples

<ul class="books" ng-repeat="book in books |  orderBy:'title'">

<ul class="books" ng-repeat="book in books | filter:searchBookTitle  | orderBy:'-year'">

Routing

  1. Import the ngRoute module from http://cdnjs.com/libraries/angular.js/
  2. Inject the routeProvider into the myApp module
  3. configure 4 routes, /, /books, /movies, /other
  4. create 2 directories views/ and controllers/
  5. create 4 new views, and 3 new controllers
  6. include the new js controller files into index.html
  7. test, commit
  8. add 4 navigation links
  9. test, commit
  10. tag as step20_routing

Inject and Configure $routeProvider

and split the views and controllers into separate files

Routing html5 mode

  1. Enable $locationProvider.html5Mode in myApp config
  2. set requireBase option to false
  3. refactor the nav link urls
  4. test, commit
  5. tag as step21_routing_html5_mode

Inject $locationProvider to enable html5mode to use prettier urls

Default Route

  1. Add $routeProvider.otherwise to the myApp config
  2. configure it to render a 404.html template
  3. create a simple 404.html page
  4. test
  5. update server.js to render the index.html file by default
  6. test
  7. commit
  8. tag as step22_default_route

Use $routeProvider.otherwise to set a default 404 route 

fails!

RouteProvider

Code Samples

$routeProvider
 .when('/', {
     templateUrl : 'views/default.html'
  })                                                                                                                                                           
  when('/books', {                                                                                                                                      
     templateUrl : 'views/books.html',                                                                                                                             
     controller : 'BooksController'                                                                                                                           
  });

Animation

  1. Import the ngAnimate module from http://cdnjs.com/libraries/angular.js/
  2. Create and import the css/animations.css file
  3. Copy Pasta the following css source

Animate the changing of views using ngAnimate

Animation

animations.css

.ng-enter {
  transition-delay: 0.5s;
  transition:0.5s linear all;
  opacity:0;
}
.ng-enter.ng-enter-active {
  transition-delay: 0.5s;
  opacity:1;
}
.ng-leave {
  transition:0.5s linear all;
  opacity:1;

}
.ng-leave.ng-leave-active {
  opacity:0;
  margin-left:20px;
}
.fade.ng-leave {
  animation: my_fade_animation 0.5s linear;
  -webkit-animation: my_fade_animation 0.5s linear;
}
@keyframes my_fade_animation {
    from { opacity:1;  }
      to { opacity:0;  margin-left:20px; }
}
@-webkit-keyframes my_fade_animation {
    from { opacity:1;  }
      to { opacity:0;  margin-left:20px;}
}

Animation

  1. test routes
  2. test books
  3. commit
  4. tag as step23_animation

Resources

Copy of Interactive Intro to AngularJS

By Ray Farias

Copy of Interactive Intro to AngularJS

Intro

  • 1,477