Angularjs
Jump to navigation
Jump to search
Angularjs
Angularjs Training Materials
Copyright Notice
Copyright © 2004-2023 by NobleProg Limited All rights reserved.
This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise.
What is Angular JS? ⌘
- HTML5, CSS and JavaScript
- JSON and Ajax
- Angular JS Applications
- Models
- Bindings
Intro ⌘
- Started in 2009 by Miško Hevery, a Google employee
- First version 2012
- Officially supported by Google
- AngularJS extends HTML with new attributes
- Great for Single Page Applications (SPAs)
- Based on simplified jQuery core
Intro con't ⌘
- JavaScript framework usually added to an HTML page with a <script> tag
- Extends HTML attributes with Directives
- Binds data to HTML with Expressions
- Based on
- Model View Controller (MVC) methodology
- Dependency Injection (DI)
Main components ⌘
Idea | Explanation |
---|---|
Template | HTML with additional markup |
Directives | extend HTML with custom attributes and elements |
Model | the data shown to the user in the view and with which the user interacts |
Scope | context for model accessible by controllers, directives and expressions |
Expressions | access variables and functions from the scope |
Compiler | parses the template and instantiates directives and expressions |
Filter | formats the value of an expression for display to the user |
View | what the user sees (the DOM) |
Data Binding | sync data between the model and the view |
Controller | the business logic behind views |
Dependency Injection | Creates and wires objects and functions |
Injector | dependency injection container |
Module | a container for the different parts of an app including controllers, services, filters, directives which configures the Injector |
Service | reusable business logic independent of views |
https://docs.angularjs.org/guide/concepts
Models ⌘
- Model binds the value of HTML controls (input, select, textarea) to application data
- ng-model directive
- Two-Way Binding
- when we change the input field, property in angular will also be changed
- validate the input (type validation: number, e-mail, required)
- data status (invalid, dirty, touched, error)
- CSS classes, depending on form field status
- ng-empty(-not-), ng-touched(-un), ng-valid(-in), ng-dirty, ng-pending, ng-pristine
Bindings ⌘
- Synchronization between the model and the view
- both updated at all times, immediately and automatically
- model changes, view reflects it, and vice versa
- Model - collection of data available for the application
- View - html container for application's display
- has access to model
- directive ng-bind, binds innerHTML to model property
- Displaying model data in the view
- expression {{ }}
- directive ng-model
- Controller - steers(adjusts) view via model
- separated from view
Model and Bindings example ⌘
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<!-- Application, View, Directives, Expression -->
<div ng-app="appy" ng-controller="steery">
<!-- Directive, Binding to View from Model with Controller-->
Who are you? <input ng-model="wayField">
<!-- Binding to View from Model via Expression -->
<h1>{{ wayField }}</h1>
<!-- Binding to View from Model via Directive -->
<p ng-bind="bindMe"></p>
</div>
<script>
// Module
var app = angular.module('appy', []);
// Controller with Scope
app.controller('steery', function($scope) {
$scope.wayField = "Knock Knock";
$scope.bindMe = "This one will work.";
});
</script>
<p ng-bind="bindMe">Why this will not work?</p>
</body>
</html>
Angular way (analysing an above example) ⌘
- There are no classes or IDs in the HTML to identify where to attach event listeners
- When 'steery' set the 'wayField' to "Knock Knock" we didn’t have to
- register any event listeners
- or write any callbacks
- 'steery' got the $scope object that it needed without having to create it
- We didn’t have to call the steery ’s constructor ourselves, or figure out when to call it
Angular way con't 1 ⌘
- Thanks to MVC our app is easier to extend, maintain, and test
- Data Binding is the ability to update, part of the DOM separately, rather than updating the whole page
- We merge template HTML strings with data
- Then insert the result where we want it in the DOM
- by setting innerHtml on a placeholder element
- To insert fresher data into the UI, or change the data based on user input
- we could just declare which parts of the UI map to which JavaScript properties
- have them sync automatically to eliminate code when writing our view and model
- most of the work in moving data from one to the other just happens automatically
Angular way con't 2 ⌘
- Dependency injection
- instead of creating dependencies, our classes just ask for what they need
- 'The Law of Demeter' design pattern (the principle of least knowledge)
- steery’s job is to set up the initial state for the model
- it shouldn’t worry about anything else, like how $scope gets created, or where to find it
- Directives
- powerful DOM transformation engine that lets us extend HTML’s syntax
- help us define the view for our app
Expressions ⌘
- Bind data to HTML
double braces: {{ expression }}
- directive: ng-bind="expression"
- Resolved and resulted precisely where written
- Similar to JavaScript expressions
- can contain literals, operators, and variables
- can be written inside HTML
- do not support conditionals, loops, and exceptions
- support filters
Expressions con't ⌘
- Simple expressions
- Values
- Objects
- Arrays
- Maps
Expressions example ⌘
<!-- numbers -->
{{ 1200 + 400 }}
<!-- strings -->
{{ mainUrl + "/" + trainingCategory + "/" + trainingName }}
<!-- objects, with double braces only -->
<div ng-app="" ng-init="training={title:'UML',duration:21}">
<p>The training title is {{ training.title }}</p>
</div>
<!-- arrays, also with ng-bind -->
<div ng-app="" ng-init="results=[9,7,5,2,8]">
<p>The second result is {{ results[1] }}</p>
<p>The fourth result is <span ng-bind="results[3]"></span></p>
</div>
Directives ⌘
- Extend HTML with new attributes
- extended HTML attributes with the prefix ng-
- Lots of built-in directives with plenty of functionalities
- ng-app, ng-init, ng-model, ng-repeat, ng-blur, ng-click, etc
- More examples http://www.w3schools.com/angular/angular_ref_directives.asp
- We can define our own directives
Directives con't ⌘
- Data typing
- Looping over arrays and arrays of objects ng-repeat
- Creating tables, handling selects ng-repeat, ng-options
- Enabling and disabling HTML elements ng-readonly
- Hiding and showing HTML elements ng-show, ng-hide
- Handling HTML events
- ng-blur, ng-change, ng-click, ng-copy, ng-cut, ng-dblclick
- ng-focus, ng-keydown, ng-keypress, ng-keyup
- ng-mousedown, ng-mouseenter, ng-mouseleave, ng-mousemove, ng-mouseover
- ng-mouseup, ng-paste
- Custom Directives
Directives example ⌘
<!-- looping with arrays -->
<div ng-app="" ng-init="courses=['UML','Drupal','MongoDB']">
<p>My favourite courses:</p>
<ul>
<li ng-repeat="c in courses">
{{ c }}
</li>
</ul>
</div>
<!-- looping with objects -->
<div ng-app="" ng-init="courseEvents=[
{venue:'London',country:'United Kingdom'},
{venue:'Warsaw',country:'Poland'},
{venue:'HongKong',country:'China'}]">
<p>Course events:</p>
<ul>
<li ng-repeat="ce in courseEvents">
{{ ce.venue + ', ' + ce.country }}</li>
</ul>
</div>
<!-- own directive -->
<body ng-app="myOwnDirective">
<!-- as html tag -->
<my-beauty-something></my-beauty-something>
<!-- as html tag's attribute -->
<div my-beauty-something></div>
<script>
var app = angular.module("myOwnDirective", []);
app.directive("myBeautySomething", function() {
return {
restrict : "A",
template : "<h1>My beauty directive!</h1>"
};
});
</script>
</body>
Controllers ⌘
- Control the data
- Regular JavaScript Objects
- Defined by ng-controller directive
- Created by a standard JavaScript object constructor
Controllers con't ⌘
- Defining controllers
- Object property functions
- Controller methods
- Controllers in external files
Controllers example ⌘
<!-- html part -->
<div ng-app="favCars" ng-controller="carsCtrl">
Color: <input type="text" ng-model="car.color"><br>
Max Speed: <input type="text" ng-model="car.maxSpeed"><br>
<br>
Full Name: {{fullDescr()}}
</div>
<script src="carsController.js"></script>
// js part, content of file "carsController.js"
var app = angular.module('favCars', []);
app.controller("carsCtrl",function($scope) {
$scope.car = {
color: "black",
maxSpeed: "320km",
};
$scope.fullDescr = function() {
var c = $scope.car;
return "This car is " + c.color + " and can drive at maximum speed of " + c.maxSpeed;
};
});
Namespaces ⌘
- Global namespace
- Modules
- Module dependencies
- Library loading
- Where to put scripts
- Application files
Modules ⌘
To configure modules in angular we use this interface
- angular.Module
- type component
- https://docs.angularjs.org/api/ng/type/angular.Module
Scopes ⌘
- angular object
- refers to the application model
- context in which expressions are executed(evaluated)
- arranged in hierarchical structure (like DOM of our app)
- can watch expressions and propagate events
Scopes con't ⌘
- when we change the model, we can observe it with API ($watch)
- to change the model not via angular usual ways(ctrls, services, etc), we can propagate it with API ($apply)
- nesting scopes
- child scopes - inheriting prototypically from parent scope
- isolate scopes
- via property - scope: { ... }
- https://docs.angularjs.org/guide/directive
Dependency Injection ⌘
- design pattern
- how components get hold of their dependencies
- angular has it's own injector subsystem
- creates components,
- resolves component's dependencies
- provides them to other components as requested
Dependency Injection con't ⌘
- when we define components
- in module's .run and .config blocks
- run - no 'providers'
- config - no 'service' and 'value'
- services, directives, filters, and animations
- injectable factory method or constructor function
- can be injected with "service" and "value" components (as dependencies)
di and just js ⌘
- DI is just a big list of key value pairs from which objects are pulled from and passed to our components.
- The way scopes work is based on prototypical inheritance.
- The $digest loop is just a task
- it iterates over expressions and watchers when Angular-related events occur
Filters ⌘
- Format and transform data
- Can be added to expressions by using the pipe character |, followed by a filter
- Convert to currency
- Array subsets
- Upper and lower case conversion
- Sorting
- Custom filter
Filters con't ⌘
- currency number to a currency
- date date to a specified format
- filter select a subset of items from an array
- json an object to a JSON string
- limitTo limits an array/string, into a specified number of elements/characters
- lowercase a string to lower case
- number a number to a string
- orderBy orders an array by an expression
- uppercase a string to upper case
Filters example ⌘
<div ng-app="bestB" ng-controller="booksCtrl">
<p>Best books ever:</p>
<ul>
<li ng-repeat="b in books | orderBy:'title'">
{{ b.author + ', ' + b.title }}
</li>
</ul>
</div>
<script>
angular.module('bestB', []).controller('booksCtrl', function($scope) {
$scope.books = [
{author:'God',title:'Bible'},
{author:'Pratchett',title:'Discworld'},
{author:'Vujcic',title:'Live without the limbs'},
{author:'Silverberg',title:'We come with dead people'},
{author:'Lewis',title:'Chronicles of Narnia'},
];
});
</script>
HTTP Requests ⌘
- Reading data from remote servers
- service $http
- makes a request to the server, and returns a response
HTTP Requests con't ⌘
- General requests
- Shortcuts
- .delete(), .get(), .head(), .jsonp(), .patch(), .post(), .put()
- Success and error handling
- Setting HTTP headers
- JSON and XSRF vulnerability protection
HTTP Req Example ⌘
<div ng-app="httpReq" ng-controller="httpReqCtrl">
<h1>{{content}}</h1>
</div>
<p>Different functions on success and failure.</p>
<script>
var app = angular.module('httpReq', []);
app.controller('httpReqCtrl', function($scope, $http) {
$http.get("badfilename.htm")
.then(function(response) {
$scope.content = response.data;
}, function(response) {
$scope.content = "Oh, my .. You can't see the result.. )-: ";
});
});
</script>
Forms ⌘
- Data-binding and validation of input controls
- HTML input control
- Browser versus Angular JS validation
- Validating input values
- Displaying input error messages
HTML input controls ⌘
- input elements
- checkbox, radiobuttons, selectbox
- select elements
- button elements
- textarea elements
Form Examples ⌘
<!-- checkbox example -->
<form>
Do you like it? :
<input type="checkbox" ng-model="varYes">
</form>
<h1 ng-show="varYes">That's great, it likes you too (-;</h1>
<!-- radiobuttons example -->
<form>
Do you like it?:
<input type="radio" ng-model="varYes" value="y">Yes
<input type="radio" ng-model="varYes" value="n">No
<input type="radio" ng-model="varYes" value="d">Not sure
</form>
<!-- selectbox example -->
<form>
Do you like it?:
<select ng-model="varYes">
<option value="">
<option value="y">Yes
<option value="n">No
<option value="d">Don't know
</select>
</form>
<!-- switch for radiobuttons and selectbox examples -->
<div ng-switch="varYes">
<div ng-switch-when="y">
<p>Oh, great!</p>
</div>
<div ng-switch-when="n">
<p>What a shame..</p>
</div>
<div ng-switch-when="d">
<p>You sure be more sure (-:</p>
</div>
</div>
Browser versus Angular JS validation ⌘
- client-side form validation
- monitors the state of the form and input fields (input, textarea, select)
- lets to notify the user about the current state
- holds information about whether they have been touched, or modified, or not
- standard HTML5 attributes can also be used to validate input
- novalidate html5 attribute disables any default browser validation
- own validation function
Validation Example ⌘
<form ng-app="validApp" ng-controller="validCtrl" name="valForm" novalidate>
<p>Hero name:<br>
<input type="text" name="heroInp" ng-model="hero" required>
<span style="color:pink" ng-show="valForm.heroInp.$dirty && valForm.heroInp.$invalid">
<span ng-show="valForm.heroInp.$error.required">Hero name is humongously needed!</span>
</span>
</p>
<p>Hero Email:<br>
<input type="email" name="email" ng-model="email" required>
<span style="color:red" ng-show="valForm.email.$dirty && valForm.email.$invalid">
<span ng-show="valForm.email.$error.required">Hey, give me the Email, Mate!</span>
<span ng-show="valForm.email.$error.email">Oups! Don't cheat!</span>
</span>
</p>
<p>
<input type="submit" ng-disabled="valForm.heroInp.$dirty && valForm.heroInp.$invalid || valForm.email.$dirty && valForm.email.$invalid">
</p>
</form>
<script>
var app = angular.module('validApp', []);
app.controller('validCtrl', function($scope) {
$scope.hero = 'Captain Carrot';
$scope.email = 'captain.carrot@gmail.com';
});
</script>
Angular Modules ⌘
- Services
- Animation
- REST
- Cookies
- Mobile device support
Services ⌘
- Function, or object, that is available for, and limited to, our AngularJS app
- Many built-in services
- $location, $http
- To use additional service in the controller, it must be defined as a dependency
- is passed in to the controller as an argument
- We still can use DOM objects like 'window.location'
- but it would have some limitations for our AngularJS app
- angular 'prefers' that we use it's own services
- Our own service
Service Example
<div ng-app="myApp" ng-controller="myCtrl">
<p>The url of this page is:</p>
<h3>{{myUrl}}</h3>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $location) {
$scope.myUrl = $location.absUrl();
});
</script>
Animations ⌘
- Animated transitions, with help from CSS (add and remove classes)
- Transformation of an HTML element gives us an illusion of motion
- Additional angular Animate library
var app = angular.module('myApp', ['ngAnimate']);
Animation Example ⌘
<style>
div {
transition: all linear 0.5s;
background-color: lightblue;
height: 100px;
width: 100%;
position: relative;
top: 0;
left: 0;
}
.ng-hide {
height: 0;
width: 0;
background-color: transparent;
top:-200px;
left: 200px;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.js"></script>
<body ng-app="anim">
<h1>Make the magic: <input type="checkbox" ng-model="animCh"></h1>
<div ng-hide="animCh"></div>
Single Page Application Concept ⌘
- Routing in Single Page Application (SPA)
- ngRoute module
- Examples of simple SPAs
- TODOs list
- PhoneCat example
Router Example ⌘
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<body ng-app="routeApp">
<p><a href="#/">Main(iac)</a></p>
<a href="#aboutus">AboutUs</a>
<a href="#contact">Contact</a>
<!-- new Directive from ngRoute library -->
<div ng-view></div>
<script>
var app = angular.module("routeApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/aboutus", {
template : "<h1>We</h1><p>We are the best!</p>"
})
.when("/contact", {
template : "<h1>Contact</h1><p>Forget about my mail and phone number!!</p>"
})
.otherwise({
template : "<h1>Nope</h1><p>Why didn't you try to click on something?</p>"
});
});
</script>
<body>
Debugging and IDEs ⌘
- batarang (chrome only)
- ng-inspector (more browsers)
- console
- angular.reloadWithDebugInfo();
- angular.element($0)
- angular.element($0).scope()
- angular.element($0).scope().$parent
- $scope
- webstorm, sublime, visual studio, atom
Exercises ⌘
0. Sum up: In Angular: (This also references script order for loading) Module wraps everything in the App. Controller talks to the View via Model. Model handles scope (is scope). Filter sorts the data. Service sets up for example REST server, or just pure http. Directive extends html with new Attribute(also tag, css class, comment). Route serves paths. Expression binds data between input(user) and the database. 1. Exercise: Case: How to use value from $rootScope inside our controller? Do it in two ways (-: HINT: - Try to rewrite this example: http://www.w3schools.com/angular/tryit.asp?filename=try_ng_scope_rootscope 2. Exercise: Create small website locally. 2.1. It should show ordered html list of elements (let's say your 3 favourite movies) 2.2. Use angular and create in the Module application for this "ol" 2.3. Angular should handle gathering data for the all "li" elements in the loop (use proper Directive) 2.4. Angular should use Controller to manage variables 2.5. Use angular to Filter the movies and provide descending order of them 2.6. Make View, which will keep "ol" separated and will be injected in main view(html document) PLAN: Create HTML views - Create a module that contains the main view (DATA) - Write the controller that helps talk to the rest of the application - Write the Model that contains the $Scope that delineates the values (movies) - Establish the filter and what fields it will filter based on the data - Include an expression to populate the data to the front end (from the scope) - Cut the "ol" from the main view, put it in the angular view and include it via Directive 2.7. Use inline edit in moviexerc. Copy the whole project and create new application, it should keep two modules: - one for list of movies, - second for inline-edit'able title 'List of my fav movies' Hint: Try to use this library: http://vitalets.github.io/angular-xeditable/ 2.7.1. Make your app bowerized (-: 2.7.2. Implement this library in the simplest possible way: http://www.cssscript.com/demo/beautiful-native-javascript-alert-replacement-sweet-alert/ 3. Exercise: Another website should show some data about potential customer. It should: - use controller to provide default data: customer's name 'Naomi', cutomer's address '1600 Amphitheatre' - have implemented your own custom angular 'Directive' and bind/invoke it in all possible ways: attribute, tag, class, comment -- this directive should be restricted only to tag and attribute -- test it, try to invoke also as class and comment - have structure of folders: js, partials(same meaning as views) - use 'partial html template'(view) with angular 'Expressions' 4. Exercise: Case: To simplify training coordinator's work (compare to example in apache/mysql/php/jquery/drupal shown by trainer) 4.1. Validate polish PESEL field (value example 82010901858): - PESEL field should be required - Make sure PESEL is correct (one angular module/controller should be responsible) HINT: google PESEL algorythm 4.2. Prepopulate dynamically Date of birth field from PESEL field - get date of birth from it (include also algorythm for century 2000-2100, value example 15252305986) - bind it into Date of birth input field (with this format '1982-01-09'), do it dynamically when user type PESEL in first input field 5. Exercise: Case: Write your own custom filter that title-cased strings for your headings in main html template. 6. Exercise: Write your custom service, which will find the person with the longest first name and longest last name from the list of users. Use this service in a filter connected to select list field. 7. Exercise: Case: Write your own custom TODO list. HINT: Try to use: - methods like '.push', '.forEach' - store data in model (scope) 8. Exercise: Install another usefull start-up server example: angular seed project. 8.1. git clone --depth=1 https://github.com/angular/angular-seed.git ang_seed 8.2. In 'README.md' find a way to start the server. 8.3. Play with deafult example there (index.html) 9. Exercise: Case: Create simple 'Mail' app. 9.0. Make it on top of your 'ang_seed' server from the last exercise (no 8) 9.1. It should keep one main view(index.html), second for list of emails(list.html), third for one email(detail.html). 9.2. Controller: - should keep some fake mails (array of objects: id, sender, subject, date, message) in jsoned variable - and have simple mapping between URLs, templates and controllers 9.3. Create REST API and 'end-point' in it with jsoned list of emails - keep list of all mails as 'mails.json' file - every single mail should have it's own '.json' file *9.4. Prepare 'add mail' functionality HINTS: Use: - 'html Table' in 'angular way', - routes($routeProvider) - learn from default example in 'ang_seed' - for date format use for example this 'Dec 6, 2013 20:35:02' - Use pure '$http' service and later improve it with 'angular-resource' library and cerate services with '.factory' - make sure your '*.json' files are formed correctly - if you want to start the http server manually: -- node node_modules/http-server/bin/http-server -a localhost -p 8000 -c-1 ./app 10. Exercise: Case: AJAX requests via $http service Create small app which will get list of emails from the previous exercise. 11. Exercise: Case: Fix it! Fix to-do list app in folder 'newtodo00'.