Introduction to AngularJS

Pete Bacon Darwin

AngularJS 1.x Team Lead

FoodMe App

AngularJS Basics

Directives

  • Adds behaviour to HTML
  • ng-app - defines your Angular App

Scope

  • Scope provides the data to the view

Data Binding

  • {{ ... }} interpolation
  • ng-model two-way binding

Step 1

Add Angular and basic bindings to the page:

  • Load angular.js
  • Add `ng-app` directive
  • bind inputs to models with `ng-model` directive
  • display models with `{{ ... }}` interpolation bindings

Step 2

Show and hide parts of the page dynamically

More directives

  • ng-show / ng-hide

  • ng-click

Step 2

Show and hide parts of the page dynamically

  • Show the form if `deliveryForm.visible`, using `ng-show`
  • Hide the delivery info `deliveryInfo.visible`, using `ng-hide`
  • Change `deliveryInfo.visible`, using `ng-click`

Angular Building Blocks

  • Modules - define components
  • Controllers - provide logic for a view
  • Services - singleton helper objects and functions

Step 3

Move the deliveryForm behaviour into a Controller

Step 3

Move the deliveryForm behaviour into a Controller

  • create an `app` module and a `FoodMeController` controller in `app.js`
  • load the `app.js` file in the index.html page
  • initialize the scope with a deliveryForm object
  • add `showDeliveryForm()` and `hideDeliveryForm()` helper methods to `FoodMeController`

Step 4

Add a list of restaurants to choose from

Scope Hierarchy

  • There is more than one scope
  • $root scope
    • child scope 1
      • grandchild scope
    • child scope 2
  • Useful for structural directives
    • ng-repeat
    • ng-if

Step 4

Add a list of restaurants to choose from

  • Initialize a mock list of restaurants on the scope in the `FoodMeController`
  • Bind the template to the list of restaurants using `ng-repeat` directive

Step 5

Implement sorting of the restaurant list

Angular Filters

  • Functions that modify interpolated data bindings
  • { someValue | myFilter : someParam }
  • Built-in
    • uppercase
    • currency
    • orderBy
    • filter

Step 5a

Implement sorting of the restaurant list

  • Initialize `sortProperty` and `sortDirection` on the scope for sorting columns
  • Add a `orderBy` filter to the `ng-repeat` using this properties: `ng-repeat="restaurant in restaurants | orderBy : sortProperty : sortDirection"`

Step 5b

Implement sorting of the restaurant list

  • Create helper methods in the controller, `sortBy(property)` and `getSortClass(property)`
  • Convert the table headings to clickable anchors with `ng-click="sortBy('name')"` directives
  • Display sort direction up/down markers using `ng-class="getSortClass('name')"` directives

Step 6

Create custom filter to display price and rating

Step 6

Create custom filter to display price and rating

  • Create a custom `rating` filter in the `app` module - we must use `$sce.trustAsHtml` since we are generating HTML.
  • Use the filter in the price and rating fields, with the `ng-bind-html` directive

Step 7

Add validation to delivery form

Step 7

Add validation to delivery form

  • Load the `../js/angular-messages.js` file
  • Add the `ngMessages` modules as a dependency of our `app` module
  • Use `ng-messages` directive to display errors
  • Fix up the initial value of `deliveryForm.visible` inside an `$scope.$evalAsync()` call

Step 8

Persist the delivery info in the local storage

Step 8

Persist the delivery info in the local storage

  • Create a `localStorage' service to wrap the browser's localStorage object
  • Create a `localStorageBinding` service that connects a property on the scope to the localStorage
  • Load the new `localStorage.js` file
  • Add the new `localStorage` module as a dependency to our `app` module
  • Bind the `user` object to the localStorage using the `localStorageBinding` service

Cross Origin Requests

  • Browser Security Feature
  • Can only make HTTP requests to your own origin
  • Possible Solutions
    • Server Proxy
    • JSONP
    • CORS

Step 9 (remote)

Load the restaurant data from a server

  • Add the `$http` dependency to the `FoodmeController`
  • Replace the static data with a call to get the restaurant data from a remote REST service (https://foodme.firebaseio.com/.json)

Step 9 (local)

Hosting App and Data Locally

  • Install a local webserver
  • Start the server in the root of the project
  • Browse to the application via this server: `http://localhost:8080/step-9`
  • Get the restaurant data from the local server

Step 10

Filter the restaurants by price and rating

Step 10

Filter the restaurants by price and rating

  • Add a new form to the left of the restaurant list
  • Initialize the filters to `null`
  • Watch the price and rating values and filter the restaurant list accordingly
  • Change the `ng-repeat` directive to use the `filteredRestaurants`

Step 11

Add a cool rating directive for use in filtering

Custom Directives

  • Define your own directives
  • Provide templates and behaviour
  • Request a new inner scope
  • Bind values to the inner scope
  • Interact with the DOM

Step 11

Add a cool rating directive for use in filtering

  • Create a new file `rating.js` containing a `rating` module
  • Load the `rating.js` file into the app
  • Add the `rating` module as a dependency of our `app` module
  • Define a `fmRating` directive in the `rating` module
  • Use this directive in the Filter Restaurants form instead of the simple text input boxes

Step 12

Display the number of filtered restaurants

  • Add a binding to the length of the `filteredRestaurants` collection using `ng-pluralize` directive

Step 13

Add transition animations to the delivery form

  • Load `../js/angular-animate.js` file into the app
  • Add a dependency on `ngAnimate` to the `app` module
  • Add new class (`fade`) to the delivery form and delivery info elements to be animated

Step 14

Display details and menu for individual restaurants

  • Exercise for the reader!
  • Hint - look at ng-view and $route

Introduction to AngularJS

By Pete Bacon Darwin

Introduction to AngularJS

  • 1,796