AngularJS and SPA

38
AngularJS & SPA Lorenzo Dematte' For 33Dev @ Muse

description

Introduction to AngularJS as a framework to build Single Page Applications

Transcript of AngularJS and SPA

Page 1: AngularJS and SPA

AngularJS & SPA

Lorenzo Dematte'For 33Dev @ Muse

Page 2: AngularJS and SPA

A) server-side generator, “forms” like (aspx, Jsp/Jsf)B) server-side templating (Haml, Mustache, Smarty)C) server-side MVC frameworksD) jQueryE) Another Javascript framework

A= ?? B = ?? C = ?? D = ?? E = ??

What are you using to build web applications?

Page 3: AngularJS and SPA

(the only image in this slide set. Now we can move on..)

Page 4: AngularJS and SPA

What is AngularJS?

A complete framework for rich SPA applications

Page 5: AngularJS and SPA

What is a SPA?

● Single Page Application● Client side (with server-side help)● Rich, responsive, fast● Desktop-like experience● “Like the big ones” (Twitter, FB, Gmail)

Page 6: AngularJS and SPA

SPA technically

● HTML5 + JS● Service● More likely:

– An MVC/MVVM client framework– Lightweight REST/Json service(s)

● Even Json non-relational DBs!

Page 7: AngularJS and SPA

DOM Manipulation

● It' central● But... Angular hides it!

Page 8: AngularJS and SPA

AngularJS vs. jQuery

● Don't design your page, and then change it with DOM manipulations

● The view is the "official record"● → Data binding

– The “Angular” way

Page 9: AngularJS and SPA

<!DOCTYPE html><html data-ng-app="myapp"><head>

<title>Foo Car rental</title> <script src="scripts/jquery-1.9.1.min.js"></script>

<script src="scripts/angular.min.js"></script><script src="scripts/myapp.js"></script>

<body> ... Name: <input type=”text” ng-model=”name” /> {{ name }}

1: Directives and data-binding

Page 10: AngularJS and SPA

Demo one

Page 11: AngularJS and SPA

More directives: ng-repeat, expression, filters

<div ng-init="friends = [ {name:'John', age:25, gender:'boy'}, {name:'Jessie', age:30, gender:'girl'}, {name:'Johanna', age:28, gender:'girl'}, {name:'Joy', age:15, gender:'girl'}, {name:'Mary', age:28, gender:'girl'}, {name:'Peter', age:95, gender:'boy'}, {name:'Sebastian', age:50, gender:'boy'}, {name:'Erika', age:27, gender:'girl'}, {name:'Patrick', age:40, gender:'boy'}, {name:'Samantha', age:60, gender:'girl'} ]"> I have {{friends.length}} friends. They are: <input type="search" ng-model="q" placeholder="filter friends..." /> <ul class="example-animate-container"> <li class="animate-repeat" ng-repeat="friend in friends | filter:q"> [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old. </li> </ul> </div>

Page 12: AngularJS and SPA

Demo two

Page 13: AngularJS and SPA

Filters

<div>{{ 12345.67 | currency }}</div>

<div>{{ 1288323623006 | date:"mediumDate" }}</div>

<ul ng-repeat="r in result.results | orderBy:sortBy">

<ul ng-repeat="r in result.results | filter:searchTerm | limitTo:10” >

(custom filters)

app.filter("orru", function(){ return function(text, length){ return text; // Do nothing }});

Page 14: AngularJS and SPA

Demo three

Page 15: AngularJS and SPA

2: Views, Controller, Scope

View Data

Page 16: AngularJS and SPA

2: Views, Controller, Scope

View Data

Html Javascript objects/JSON/something remote

Page 17: AngularJS and SPA

2: Views, Controller, Scope

View Data

Html Javascript objects/JSON/something remote

Page 18: AngularJS and SPA

2: Views, Controller, Scope

ViewData

(Model)

ViewModel

(bi-directional)binding

Page 19: AngularJS and SPA

2: Views, Controller, Scope

ViewData

(Model)

Controller

Update(query)

Input(select)

Page 20: AngularJS and SPA

2: Views, Controller, Scope

ViewData

(Model)

$scope

(bi-directional)binding

Controller

Page 21: AngularJS and SPA

Controllers

<!DOCTYPE html><html data-ng-app="myapp"><head>

<title>Foo Car rental</title> <script src="scripts/jquery-1.9.1.min.js"></script>

<script src="scripts/angular.min.js"></script><script src="scripts/myapp.js"></script>

<body><div class="container-narrow">

<div data-ng-controller="SomeController"><div class="masthead" data-ng-show="showNavigation()">

... Name: <input type=”text” ng-model=”name” /> {{ name }}

Page 22: AngularJS and SPA

Controllers

var myApp = angular.module("myApp", []);

myApp.controller('SomeController', function ($scope, someService) {

$scope.name = “Pippo”;

$scope.showNavigation = function() { if (pathUnder("/login") || pathUnder("/registration")) return false; else return true;};

});

Page 23: AngularJS and SPA

Demo four

Page 24: AngularJS and SPA

3: Modules, routes, factories/services

Page 25: AngularJS and SPA

Modules and dependency injection

var myApp = angular.module("myApp", []);

myApp.controller('SomeController', function ($scope, someService) {

$scope.name = “Pippo”;

$scope.showNavigation = function() { if (pathUnder("/login") || pathUnder("/registration")) return false; else return true;};

});

???

Page 26: AngularJS and SPA

RoutesApp.config(function ($routeProvider) {

$routeProvider.when('/', {

controller: 'HomeController', templateUrl: 'partials/home.html'

}).when('/user-info', {

controller: 'UserController', templateUrl: 'partials/user-info.html'

}).when('/login', { controller: 'LoginController',

templateUrl: 'partials/login.html'}).when('/registration', { controller: 'LoginController',

templateUrl: 'partials/registration.html'}).when('/invalid-server-response', { controller: 'UserController',

templateUrl: 'partials/invalid-server-response.html'}).when('/error', { controller: 'UserController',

templateUrl: 'partials/error.html'}).otherwise({ redirectTo: '/' });

});

Page 27: AngularJS and SPA

Routes and views

<div data-ng-view=""></div>

“Partials”

Page 28: AngularJS and SPA

Servicesangular.module("MiniResources", [], ["$provide", function($provide) { $provide.value("miniResources", { nameRequired : "E' necessario specificare un nome",

fieldAdded: "Campo aggiunto con successo",emptyField: "<vuoto>",startFlowQuestion: "Sei sicuro di voler cominicare un flusso",startFlow: "Comincia un nuovo flusso",yes: "Si",no: "No",back: "Torna indietro",all: "Tutti",processing: "Sto elaborando",error: "Errore",close: "Chiudi"

});}]);

Page 29: AngularJS and SPA

Service usage

● They are injected!

miniApp.controller("StepController", function ($scope, …, miniResources)

Page 30: AngularJS and SPA

Demo five

Page 31: AngularJS and SPA

4: Custom directivesapp.directive('ngContent', function ($parse) { return { restrict: 'A', require: '?ngModel', link: function (scope, element, attrs) { if (attrs.ngModel && element.text()) { $parse(attrs.ngModel).assign(scope, element.text()); } scope.$watch(attrs.ngModel, function(value) { element.text(value); }); } };});

Where?

require: '^parentDirective' will give you access to the parentDirective

^ -- Look for the controller on parent elements, not just on the local scope? -- Don't raise an error if the controller isn't found

Page 32: AngularJS and SPA

Demo six

Page 33: AngularJS and SPA

5: UI

Page 34: AngularJS and SPA

UI elements in Angular<h4>Static arrays</h4> <pre>Model: {{selected | json}}</pre> <input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control">

<h4>Asynchronous results</h4> <pre>Model: {{asyncSelected | json}}</pre> <input type="text" ng-model="asyncSelected" placeholder="Locations loaded via $http" typeahead="address for address in getLocation($viewValue) | filter:$viewValue" typeahead-loading="loadingLocations" class="form-control">

Page 35: AngularJS and SPA

Demo seven

Page 36: AngularJS and SPA

...but... in the real world?

● #1: Javascript vs. “Security through obscurity” (F12 - but it is actually good because...)

● #2: you have to design a SPA keeping #1 in mind

● #3: SPA are almost never “single page”● #4: HTTPS and/or OAuth!

Page 37: AngularJS and SPA

In the real world...

● You almost always “blur” the lines– Server-side generation AND client-side rendering– Multiple pages for multiple roles– Use your server!

Page 38: AngularJS and SPA

Thank you!