Pré-requis :
- avoir suivi les mini-cours dédiés au HTML, CSS et JavaScript
- connaître l'anglais écrit
Introduction
AngularJS est un framework (une bibliothèque) qui permet de créer plus facilement des applications web. Il suffit d'ajouter une seule ligne à son code HTML pour bénéficier de cette facilité. Ici, la version 1.6.9 :
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script> </head> ...
Donc, l'application web ne fonctionnera que si l'utilisateur est connecté.
Il est recommandé de placer ce Javacript dans le <head>
.
Télécharger (=> enregistrer le lien sous) : angular.min.js
(version 1.6.9)
While it is common in HTML applications to place scripts at the end of the
<body> element, it is recommended that you load the AngularJS library either in the
<head> or at the start of the <body>. This is because calls to angular.module
can only be compiled after the library has been loaded.
Le HTML 5 permet d'ajouter aux balises HTML n'importe quels attributs à condition que
leurs noms débutent par data-
.
Les directives
Les directives sont de nouveaux attributs de balises HTML. Pour que le
code HTML 5 soit valide, ces noms doivent donc être préfixé par data-
.
-
ng-app
: Généralement placée dans une balise <div> ou <form>, elle permet de définir la zone de la page web qui correspond à une application.<div data-ng-app="myApp"> ... </div>
Toutes les autres directives seront placées dans cette zone.
En l'absence de controller, la valeur de cet attribut doit être vide .<div data-ng-app=""> ... </div>
-
ng-model
: Cette directive permet de lier la valeur d'un contrôle HTML (input, select, textarea
) à une variable de l'application web. Le nom de cette variable correspond à la valeur de l'attribut HTML (data-ng-model
).Dans
<input data-ng-model="mon_nom" />
,mon_nom
est la valeur de l'attribut HTML et le nom de la variable AngularJS. Dès que l'utilisateur modifie le champ (la valeur de la balise input), la valeur de la variable [de l'application] AngularJS change instantanément.
Les expressions
Les expressions AngularJS peuvent contenir des littéraux (nombre et chaîne de caractères), des opérateurs (arithmétiques ( + * - / % ), logiques (&& || ! ) et relationnels( < <= == != > >= ), des parenthèses, des variables, true et false, des noms de propriétés d'objet, ... (comme en JavaScript).
Une variable peut aussi être un nom de tableau ou un objet.
Quelques exemples d'expression :
3.1415926535 2+2 "Thibaut" 'PIGNÉ' "Thibaut"+'PIGNÉ' nom (2.5 + 0.5 ) * 4 points[2] personne.nom !true 17<18 (17<18)&&(17>18) ('PIGNÉ').length 'PIGNÉ'+5
Ci-dessus, nom
est un nom de variable. Le résultat de cette
expression vaut le contenu de cette variable.
Utilisation d'une expression
Pour afficher une expression, on peut utiliser la directive
ng-bind
, car elle lie le résultat de l'expression AngularJS
à la méthode JavaScript innerHTML de l'élément HTML (ci-dessous,
<span>
) qui la contient.
<p>Valeur de l'expression : <span data-ng-bind="expression"></span></p>
Toutefois, en pratique, on préfère utiliser {{
expression }}
,
car, placé dans le contenu d'une balise - c'est-à-dire entre la balise ouvrante et
fermante - il affiche le résultat de l'expression; et, placé dans la
balise, le résultat de l'expression est utilisé comme valeur dans un
attribut (comme nous le voyons dans notre première application web pour changer
la couleur de fond d'un champ).
<p>{{ expression }}</p> <input ... style="background-color:{{couleur}}" />
Les espaces dans {{ }}
sont facultatifs. Ils permettent une meilleure
lisibilité du code. {{expression}}
=
{{ expression }}
Ma première application web
Code HTML de l'application web :
... <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script> </head> <body> ... <!-- début de l'application AngularJS --> <div data-ng-app="" data-ng-init="nom='LEDRU';points=[1,15,19,2,40]; personne={nom:'EINSTEIN',prenom:'Albert'}"> ... <p> Affichage de résultats d'expressions avec la directive <code>ng-bind</code> : </p> <aside> <p> 3.1415926535 = <span data-ng-bind="3.1415926535"></span><br /> 2+2 = <span data-ng-bind="2+2"></span><br /> "Thibaut" = <span data-ng-bind='"Thibaut"'></span><br /> 'PIGNÉ' = <span data-ng-bind="'PIGNÉ'"></span><br /> 'Thibaut'+' '+'PIGNÉ' = <span data-ng-bind="'Thibaut'+' '+'PIGNÉ'"></span><br /> nom = <span data-ng-bind="nom"></span><br /> (2.5 + 0.5 ) * 4 = <span data-ng-bind="(2.5 + 0.5 ) * 4"></span><br /> points[2] = <span data-ng-bind="points[2]"></span><br /> personne.nom = <span data-ng-bind="personne.nom"></span><br /> !true = <span data-ng-bind="!true"></span><br /> 17 < 18 = <span data-ng-bind="17 < 18"></span><br /> (17<18)&&(17>18) = <span data-ng-bind="(17<18)&&(17>18)"></span><br /> ('PIGNÉ').length = <span data-ng-bind="('PIGNÉ').length"></span><br /> 'PIGNÉ'+5 = <span data-ng-bind="'PIGNÉ'+5"></span><br /> </p> </aside> ... <p>Résultats d'expressions :</p> <aside> <p> {{3.1415926535}}<br /> {{2+2}}<br /> {{"Thibaut"}}<br /> {{'PIGNÉ'}}<br /> {{"Thibaut"+'PIGNÉ'}}<br /> {{nom}}<br /> {{(2.5 + 0.5 ) * 4}}<br /> {{points[2]}}<br /> {{personne.nom}}<br /> {{!true}}<br /> {{17 < 18}} {{(17<18)&&(17>18)}}<br /> {{('PIGNÉ').length}}<br /> {{'PIGNÉ'+5}}<br /> </p> </aside> ... <aside> <p> Mon nom : <input type="text" data-ng-model="mon_nom" /> </p> <p> Le nom que j'ai tapé est : {{ mon_nom }}<br> Le nom que j'ai tapé est : <span data-ng-bind="mon_nom"></span> </p> </aside> ... <aside> <p> Tapez le nom d'une couleur de fond (blue, red, ...) pour ce champ : <input type="text" data-ng-model="couleur" style="background-color:{{couleur}}" placeholder="blue" /> </p> </aside> </div> <!-- fin de l'application AngularJS -->
nom
est un nom de variable (simple) dont la valeur a été
initialisée à 'LEDRU', via la directive ng-init
<div data-ng-app=""
data-ng-init="nom='LEDRU';...">
personne
= le nom d'une variable (objet)
Dans le code source de la zone de l'application AngularJS, on ne peut pas taper des doubles accolades - {{ }} ou {{ }} - sans qu'ils soient automatiquement interprétés.
Les doubles accolades ne peuvent pas contenir des doubles accolades.
Pour mieux délimiter la zone d'application, une couleur de fond est appliquée.
Application AngularJS
Affichage de résultats d'expressions avec la directive ng-bind
:
Affichage de résultats d'expressions avec les doubles accolades :
Les doubles accolades peuvent être tapées dans le contenu d'une balise, mais aussi dans la balise !
Créer une mini-application web est très facile.
Résumé
Vous savez déjà l'essentiel. Il faut :
-
lier sa page web à un framework (= ajouter une ligne dans le
<head>
) -
définir la zone de l'application web (= ajouter l'attribut
data-ng-app
) -
récolter les données de l'utilisateur (= ajouter l'attribut
data-ng-model
) -
{{
expression}}
peut être placé dans :- le contenu d'une balise, pour afficher le résultat de l'expression sur la page web.
- la balise, pour utiliser le résultat de l'expression comme valeur dans un attribut de cette balise.
- Afficher le résultat peut aussi se faire via la directive
data-ng-blind
- Une variable peut être initialisée via la directive
data-ng-init
L'initialisation se fait normalement dans le controller.
ng-controller
Le controller "contrôle" l'application. Concrètement, contient tout le code JavaScript nécessaire.
La directive ng-controller permet de donner un nom au controller. Elle est souvent placée dans la même balise que celle qui nomme l'application (car une application simple ne dispose que d'un seul controller).
<div data-ng-app="myApp" data-ng-controller="myCtrl">
Le code JavaScript pourrait être le contenu de la balise script, mais il est préférable de placer le code JavaScript dans un fichier Javascript.
myCtrl.js
angular.module('myApp',[]).controller('myCtrl', function($scope) { });
Vous pouvez recopier ce code tel quel dans vos scripts. Veillez à ce que le nom du controller dans le code HTML soit le même dans le code JS.
A controller is a JavaScript Object, created by a standard JavaScript object
constructor.
Pour initialiser la variable nom, il suffit alors de taper : $scope.nom="PIGNÉ";
angular.module('myApp',[]).controller('myCtrl', function($scope) { $scope.nom="PIGNÉ"; /* initialisation de la variable nom sans passer par ng-init */ });
$scope
$scope est un objet pouvant avoir des propriétés et/ou des méthodes qui fait la liaison entre la vue (view HTML) et le controller. $cope est un mot-clé.
When adding properties to the $scope object in the controller, the view (HTML) gets
access to these properties. In the view, you do not use the prefix $scope
If we consider an AngularJS application to consist of :
- View, which is the HTML.
- Model, which is the data available for the current view.
- Controller, which is the JavaScript function that
makes/changes/removes/controls the data.
Then the scope is the Model.
$rootScope
All applications have a $rootScope.
The rootScope is available in the entire application.
If a variable has the same name in both the current scope and in the rootScope, the
application uses the one in the current scope.
ng-repeat
La directive ng-repeat répète une balise HTML, autant de fois qu'il existe d'éléments dans une tableau ou une collection (tableau d'objets).
The ng-repeat directive is perfect for looping through an array.
<div ng-app="" ng-init="names=['Jani','Hege','Kai']"> <ul> <li ng-repeat="x in names"> {{ x }} </li> </ul> </div>
<div ng-app="" ng-init="names=[ {name:'Jani',country:'Norway'}, {name:'Hege',country:'Sweden'}, {name:'Kai',country:'Denmark'}]"> <ul> <li ng-repeat="x in names"> {{ x.name + ', ' + x.country }} </li> </ul> </div>
ng-model
With the ng-model directive you can bind the value of an input field to a
variable created in AngularJS.
The data model is a collection of data available for the application
ng-show / ng-hide / ng-disabled
Be displayed only if the expression in the ng-show attribute returns
true. You can use any expression that evaluates to true or false.
<p> 17 > 18 <span ng-show="17 > 18">vaut <em>false</em> !</span><br> 17 < 18 <span ng-show="17 < 18">vaut <em>true</em>.</span> </p> <p>17 > 18<span ng-hide="17 > 18"</span> => caché !</span><br> 17 < 18<span ng-hide="17 < 18"</span> => pas caché !</span></p>
<div ng-app="" ng-init="mySwitch=true"> <p><button ng-disabled="mySwitch">Click Me!</button></p> <p><input type="checkbox" ng-model="mySwitch">Button</p> <p>{{ mySwitch }}</p> </div>
ng-click
The event directives allows us to run AngularJS functions at certain user events.
<div ng-app="myApp" ng-controller="myCtrl"> <h1 ng-click="changeName()">{{firstname}}</h1> </div>
angular.module('myApp',[]).controller('myCtrl', function($scope) { $scope.firstname = "John"; $scope.changeName = function() { $scope.firstname = "Nelly"; } });
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
Mouse events occur when the cursor moves over an element, in this order :
ng-mouseover
ng-mouseenter
ng-mousemove
ng-mouseleave
Or when a mouse button is clicked on an element, in this order :
ng-mousedown
ng-mouseup
ng-click
If you want to show a section of HTML code when a button is clicked, and hide when the
button is clicked again, like a dropdown menu, make the button behave like a toggle
switch :
<button ng-click="myFunc()">Click Me!</button> <div ng-show="showMe"> <h1>Menu:</h1> <div>Pizza</div> <div>Pasta</div> <div>Pesce</div> </div>
$scope.showMe = false; $scope.myFunc = function() { $scope.showMe = !$scope.showMe; }
$event
You can pass the $event object as an argument when calling the function. The $event
object contains the browser's event object :
<h1 ng-mousemove="myFunc($event)">Mouse Over Me!</h1> <p>Coordinates: {{x + ', ' + y}}</p>
$scope.myFunc = function(myE) { $scope.x = myE.clientX; $scope.y = myE.clientY; }
Filters
AngularJS provides filters to transform data :
currency Format a number to a currency format.
date Format a date to a specified format.
filter Select a subset of items from an array.
json Format an object to a JSON string.
limitTo Limits an array/string, into a specified number of
elements/characters.
lowercase Format a string to lower case.
number Format a number to a string.
orderBy Orders an array by an expression.
uppercase Format a string to upper case.
Le format est celui utilisé aux États-Unis. Pour obtenir le format franco-belge (au niveau du currency, date et number, il faut ajouter le fichier angular-locale_fr-be.js après le fichier angular.min.js :
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script> <script src="angular-locale_fr-be.js"></script>
Utilisez le menu contextuel du lien pour choisir "enregistrer le lien sous ..." et ainsi télécharger le fichier (au lieu de le visualiser).
Filters can be added to expressions by using the pipe character |, followed by a
filter.
<p>The name is {{ lastName | uppercase }}</p> <li ng-repeat="x in names | orderBy:'country'"> {{ x.name + ', ' + x.country }} </li> <li ng-repeat="x in names | filter : 'i'">{{ x }}</li> <tr data-ng-repeat="x in tableReduite=(table | filter:{'e':search})"> <td>{{x.b | date}}</td> <td>{{x.c | currency}}</td>
table
est le nom d'un tableau (d'objets)
e
est le nom d'un champ (d'une propriété de l'objet)
search
est le nom d'une variable (qui contient la valeur du
champ "e" de certains objets). La valeur de cette variable est tapée par l'utilisateur
via un champ (user input)
Pour plus d'info, consultez le code-source des fichiers : tab3.htm et tab4.htm.
Services
A service is a function or object. AngularJS has about 30 built-in services. The name service is
passed in to the controller as an argument.
Ce nom est toujours préfixé par
le signe $.
Once you have created a service, and connected it to your application, you can use the
service in any controller, directive, filter, or even inside other services.
$http
This service makes a request to the server, and lets your application handle the
response. $http is an XMLHttpRequest object for requesting external
data.
angular.module('myApp',[]).controller('myCtrl', function($scope, $http) { $http.get("welcome.htm").then(function (response) { $scope.myWelcome = response.data; }); });
Method of the $http service :
.delete()
.get()
.head()
.jsonp()
.patch()
.post()
.put()
angular.module('myApp',[]).controller('myCtrl', function($scope, $http) { $http({ method : "GET", url : "welcome.htm" }).then(function mySuccess(response) { $scope.myWelcome = response.data; }, function myError(response) { $scope.myWelcome = response.statusText; }); });
The response from the server is an object with these properties :
.config the object used to generate the request.
.data a string, or an object, carrying the response from the
server.
.headers a function to use to get header information.
.status a number defining the HTTP status.
.statusText a string defining the HTTP status.
The data you get from the response is expected to be in JSON format.
JSON is a great way of transporting data
$http.get("customers.php").then(function(response) { $scope.myData = response.data.records; });
myData est un tableau d'objets (au format JSON).
$http.get() reads JSON data
Tables
The ng-repeat directive is perfect for displaying tables.
<tr ng-repeat="x in names"</tr> <td>{{ $index + 1 }}</td> <td>{{ x.Name }}</td> <td>{{ x.Country }}</td> </tr>
$index
est un mot-clé qui affiche un index qui commence à 0 et
qui s'auto-incrémente (à chaque nouvelle ligne affichée). Voir ng-repeat
$http.get("customers.php") .then(function (response) { $scope.names = response.data.records; });
To make it nice, add some CSS to the page :
table, th , td { border: 1px solid grey; border-collapse: collapse; padding: 5px; } table tr:nth-child(odd) { background-color: #f1f1f1; } table tr:nth-child(even) { background-color: #ffffff; }
Ou, utilisez le fichier w3.css et la classe w3-table-all
ng-options
To create a dropdown list, based on an array of strings :
<select ng-model="selectedName" ng-options="x for x in names"> </select>
<select> <option ng-repeat="x in names">{{x}}</option> </select>
ng-options vs ng-repeat. Dropdowns made with ng-options allows
the selected value to be an object, while dropdowns made from ng-repeat has to be
a string.
The data source was can also use an object. Assume you have an object with key-value
pairs. The expression in the ng-options attribute is a bit different for
objects :
<select ng-model="selectedCar" ng-options="x for (x, y) in cars"> </select>
x for (x, y)
=> key s'affichera dans les options; value = ce
qui sera sélectionné
y for (x, y)
=> value s'affichera dans les
options; value = ce qui sera sélectionné
The selected value will always be the value in a key-value pair.
Avec la collection suivante :
$scope.cars = { car01 : {brand : "Ford", model : "Mustang", color : "red"}, car02 : {brand : "Fiat", model : "500", color : "white"}, car03 : {brand : "Volvo", model : "XC90", color : "black"} };
<select ng-model="selectedCar" ng-options="y.brand for (x, y) in cars"> </select>
SQL
AngularJS is perfect for displaying data from a Database. Just make sure the data is
in JSON format.
Cross-Site HTTP Requests Requests for data from a different server
(than the requesting page), are called cross-site HTTP requests. Cross-site requests are
common on the web. Many pages load CSS, images, and scripts from different servers. In
modern browsers, cross-site HTTP requests from scripts are restricted to same site for
security reasons. The following line, in our PHP examples, has been added to allow
cross-site access.
<?php header("Access-Control-Allow-Origin: *"); header("Content-Type: application/json; charset=UTF-8"); $cnx = $typDB.":host=".$host.";dbname=".$dbname; $bdd = new PDO($cnx, $root, $password); $sql = "..."; $rep = $bdd->query($sql); echo json_encode($rep->fetchAll(PDO::FETCH_ASSOC)); ?>
Voir : PHP - MySQL - JSON - AngularJS
Forms
Radio buttons with the same ng-model can have different values, but only the selected
one will be used.
<input type="radio" ng-model="myVar" value="dogs">Dogs <input type="radio" ng-model="myVar" value="tuts">Tutorials <input type="radio" ng-model="myVar" value="cars">Cars
The property defined in the ng-model attribute will have the value of the selected
option in the selectbox.
<select ng-model="myVar"> <option value=""> <option value="dogs">Dogs <option value="tuts">Tutorials <option value="cars">Cars </select>
The novalidate attribute disables any default browser validation.
Validation
L'apport d'AngularJS en matière de validation d'un formulaire est insuffisant. La validation HTML et validation JS sont suffisantes (et doivent être refaites côté serveur)
Apport d'AngularJS
Input fields have the following states :
$untouched The field has not been touched yet
$touched The field has been touched
$pristine The field has not been modified yet
$dirty The field has been modified
$invalid The field content is not valid
$valid The field content is valid
Forms have the following states :
$pristine No fields have been modified yet
$dirty One or more have been modified
$invalid The form content is not valid
$valid The form content is valid
$submitted The form is submitted
AngularJS adds CSS classes to forms and input fields depending on their states. The
classes are removed if the value they represent is false.
angular Object
The Global API functions are accessed using the angular object. Below
is a list of some common API functions :
angular.lowercase() : Converts a string to lowercase
angular.uppercase() : Converts a string to uppercase
angular.isString() : Returns true if the reference is a string
angular.isNumber() : Returns true if the reference is a number
Toutes les fonctions de l'objet angular
ng-include
You can include HTML content using the ng-include directive. It can
also contain AngularJS code. By default, the ng-include directive does not allow you to
include files from other domains. To include files from another domain, you can add a
whitelist of legal files and/or domains in the config function of your application:
<div ng-include="'https://tryit.w3schools.com/angular_include.php'"></div> <script> var app = angular.module('myApp', []); app.config(function($sceDelegateProvider) { $sceDelegateProvider.resourceUrlWhitelist([ 'https://tryit.w3schools.com/**' ]); }); </script>
Be sure that the server on the destination allows cross domain file access. To allow this file to be read from other domains, it must contain the header :
<?php header("Access-Control-Allow-Origin: *"); ?>
Animations
Applications should not be filled with animations, but some animations can make the
application easier to understand.
you must include the AngularJS Animate library :
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-animate.js"><script>
Then you must refer to the ngAnimate module in your application :
<body ng-app="ngAnimate">
Or if your application has a name, add ngAnimate as a dependency in your application
module
var app = angular.module('myApp', ['ngAnimate']);
Liens :
- Tutoriel (w3schools)
- AngularJS.org
- Developper guide