00:00:00

AngularJS - Jour 3

Notes

Echanger avec un serveur

Notes

Requête HTTP

  • $http
  • Asynchrone.
  • Les objets envoyés sont transformés en JSON.
  • Le JSON reçu est transformé en objet.

Notes

Requête HTTP - $http

$http({method: 'GET', url: 'http://www.google.com/'})
  .success(function(data, status, headers, config) {
    // Success
  })
  .error(function(data, status, headers, config) {
    // Error
  });
  • $http.get
  • $http.head
  • $http.post
  • $http.put
  • $http.delete
    $http.get('http://www.google.com/');
    
    $http.post('/users', {
      data: {
        username: 'Toto',
        password: 's3cret',
      }
    });
    

Notes

Requête HTTP - Configuration d'$http

  • params : Paramètres de la requête (?key1=value1&key2=value2).
  • headers : En-têtes à ajouter à la requête.
  • cache : Activer le cache.
  • timeout : Changer le timeout de la requête.

$http

Notes

Utiliser un backend REST

Les différentes méthodes HTTP pour le REST.

  • GET : Récupérer une liste d'objets (/users) ou un objet en particulier (/users/123).
  • POST : Créer un nouvel objet (/users).
  • PUT : Modifier un objet existant (/users/123).
  • DELETE : Supprimer un objet existant (/users/123).

Notes

Utiliser un backend REST - ngResource

  • Module à ajouter : angular-resource.
  • $resource
    var User = $resource('/users/:userid', {
      userId: '@id',
    });
    
    // GET /users
    User.get(function(users) {
      // Success
    }, function(err) {
      // Error
    });
    
    // GET /users/123
    User.get({
     id: '123',
    }, function(user) {}, function(err) {});
    
    // GET /users
    User.query(function(users) {
      var user = users[0];
    }, function(err) {});
    

Notes

$resource est un service permettant de faciliter la gestion d'objets par requêtes REST. $resource est dans le module ngResource.

.get() permet de récupérer un ou des objets. query() permet de récupérer une liste d'objet.

Utiliser un backend REST - ngResource

// POST /users/123
User.save({}, {
  username: 'Toto',
  password: 's3cret',
}, function(user) {}, function(err) {});

// DELETE /users/123
User.delete({
  id: '123'
}, {}, function(resp) {}, function(err) {});

User.remove({
  id: '123'
}, {}, function(resp) {}, function(err) {});

// Exactement la même chose qu'au dessus
User.delete({}, {
  id: '123'
}, function(resp) {}, function(err) {});

Notes

save(parametres, data) pour sauvegarder les données.

delete alias de remove

Les "paramètres" de delete peuvent être mis en tant que "data".

Utiliser un backend REST - ngResource

$save / $delete / $remove

// POST /users/123
User.get({id: '123'}, function(user) {
  user.password = 'n0t s0 s3cret';
  user.$save;
});

Référence

// Asynchrone, référence vide pour le moment.
$scope.user = User.get({id: '123'});

User.get({id: '123}, function(user) {
  $scope.user = user;
});

Notes

$save, $delete et $remove feront les requêtes HTTP en fonction de l'objet.

L'appel est asynchrone est la valeur est vide tant que la requête n'est pas fini.

Utiliser un backend REST - Restangular

Restangular est un service plus avancé pour la gestion des backend REST.

// GET /users
Restangular.all('users').getList().then(function(users){
  $scope.users = users;
});

// GET /users/123
Restangular.one('users', 123).get().then(function(user){
  $scope.user = user;
});

// GET /users/123/friends
Restangular.one('users', 123).all('friends').getList().then(function(friends){
  $scope.user = user;
});

Notes

Ajoute des dépendances (Lodash). Utilise les promesses.

WebSockets

  • Permet à un client et à un serveur d'échanger en temps réél.
  • API toujours en cours de standardisation par le W3C.
  • Disponible dans angular-websocket.
    var ws = new WebSocket("ws://localhost:8000/socket/");
    
    ws.onopen = function(){
      // WebSocket ouverte
    };
    
    ws.onmessage = function(message) {
      // Nouveau message
    };
    
    ws.send('Message');
    

Notes

API Promise

Une promesse permet de résoudre une valeur de manière asynchrone (ou non) d'une manière "synchrone".

L'enfer des callback

User.get(fromId, function(user){
  user.friends.find(toId, function(friend) {
    user.sendMessage(friend, message, function(){
      // Message envoyé
    }, function(err) {
     // Erreur lors de l'envoi du message
    });
  }, function(err) {
    // Impossible de trouver l'ami
  })
}, function(err) {
  // Impossible de trouver l'utilisateur
});

Notes

Imaginont un service User permettant de récuperer un utilisateur.

API Promise

Avec des promesses

User.get(fromId)
  .then(function(user){
    return user.friends.find(toId);
  }, function(err) {
    // Impossible de trouver l'utilisateur
  })
  .then(function(friend) {
    return user.sendMessage(friend, message);
  }, function(err) {
    // Impossible de trouver l'ami
  }).then(function() {
    // Message envoyé
  }, function(err) {
    // Erreur lors de l'envoi du message
  });
  • Les appels sont correctement enchainées.
  • Les erreurs sont gérées au niveau de l'appel concerné ou remontées.
  • $http, $timeout, $interval retourne des promesses !

Notes

API Promise - $http

$http.get('http://www.google.com/').then(function(data) {
  // data – {string|Object} – Le corps de la réponse transformé (JSON => Objet).
  // status – {number} – Code HTTP de la réponse.
  // headers – {function([headerName])} – Fonction permettant de récuperer les en-têtes.
  // config – {Object} – La configuration utilisé lors de la requête.
  // statusText – {string} – Le status HTTP en texte.

  var response = data.data;
});

Notes

API Promise - $q

Créer une promesse

var deferred = $q.defer();

// Résoud la promesse
deferred.resolve(value);

// Rejette la promesse
deferred.reject(reason);

// Informe sur le status de la promesse
deferred.notify(value);

return deferred.promise;
  • $q.all(promises)
  • $q.reject(reason)
  • $q.when(value)

Notes

reject et when crééent des promesses à partir d'une valeurs.

API Promise - $q

Utiliser la promesse

  • .then(successFn, errFn, notifyFn)
  • .catch(errFn)

Notes

then retourne une promesse. Les promesses peuvent donc être chainées. catch peut être utilisé à la place du parametre errFn.

API Promise - Exemple : Création de promesse

angular.module('myApp', [])
  .factory('UserService', ['$q', '$resource', function($q, $resource) {
    var User = $resource('/users/:userid', {userId: '@id'});
    return {
      getUsers: function() {
        var deferred = $q.defer();

        User.query(function(users) {
          deferred.resolve(users);
        }, function(err) {
          deferred.reject(err);
        });

        return deferred.promise;
      },
    };
  }]);
  .controller('UserController', function($scope) {
    $scope.users = '';

    UserService.getUsers().then(function(users) {
      $scope.users = users;
    }, function(err) {
      // Erreur
    });
  });

Notes

Dans cet exemple on va juste récuperer une liste d'utilisateur depuis un backend REST.

API Promise - Exemple : $q.all() et chainage

angular.module('myApp', [])
  .controller('ViewController', function($scope, $http, $q) {
    $scope.vocabularies = {};
    $scope.cities = {};

    $http.get('/vocabularies/cities').then(function(cities) {
      $scope.vocabularies.cities = cities;

      var promises = [];
      for (var i = 0; i < $scope.vocabularies.cities.length; i++) {
        city = $scope.vocabularies.cities[i];
        promises.push($http.get('/cities/'+ city.id));
      }
      return $q.all(promises);
    }).then(function(cities) {
      $scope.cities = values;
    });
  });
});

Notes

Dans cet exemple on va récuperer une liste de ville depuis un vocabulaire puis récupérer les informations de toutes les villes.

$q.all() permet d'attendre que toutes les requêtes pour les villes aient été faites.

API Promise - Exemple : gestion des erreurs

angular.module('myApp', [])
  .controller('ViewController', function($scope, $http, $q) {
    $scope.vocabularies = {};
    $scope.cities = {};

    // Ira dans la fonction "Erreur 1" si il y a une erreur
    $http.get('/vocabularies/cities').then(function(cities) {
      $scope.vocabularies.cities = cities;

      // Ira dans la fonction "Erreur 1" si il y a une erreur
      $http.get('/cities/1').then(function(city) {
        // OK
      });

      // Ira dans la fonction "Erreur 2" si il y a une erreur
      $http.get('/cities/2').then(function(city) {
        // OK
      }, function(err) {
        // Erreur 2
      });

    }, function(err) {
      // Erreur 1
    });
  });
});

Notes

L'erreur remonte jusqu'a la promesse qui pourra la gérer.

TP - Lister les projets GitHub - 10

  • Créer un nouveau module sur l'application todo avec :
    • Une route pour /github.
    • Un contrôleur et un template.
  • Récuperer la liste des projets de l'organisation angular avec $http.
    • https://api.github.com/orgs/angular/repos
    • Lister les projets
  • Ajouter une route pour /github/:project.
    • Installer angular-resource
      • bower install --save angular-resource
    • Ajouter angular-resource.js dans index.html.
    • Affiche le détail d'un projet (nom, description, lien vers la page GitHub) (utiliser $resource).
      • https://api.github.com/repos/angular/{projet}
    • Afficher également les "pull requests" (url, titre)
      • https://api.github.com/repos/angular/{projet}/pulls
    • Ajouter un lien vers la page détaillant le projet dans la liste de projets.

Notes

Installer les dépendances Node.js avec npm

npm permet d'installer des paquets Node.js. Un fichier package.json permet de décrire un projet et contient ses dépendances ainsi que les commandes permettant de le tester/lancer.

npm init  # Créer un fichier package.json
npm install  # Utilise package.json
npm install bower  # Installe un paquet de manière locale
npm install --save bower  # Installe un paquet et l'ajoute aux dépendances
npm install --save-dev bower  # Installe un paquet et l'ajoute aux dépendances de développements
npm install -g bower  # Installe un paquet de manière globale
npm install bower==1.3.12  # Installe une version précise

Paquets - npm install

Notes

Voir le fichier package.json d'angular-seed.

Installer les dépendances web avec Bower

Bower est une application Node.js permettant de gerer les dépendances client. Un fichier bower.json contient les dépendances. Un fichier .bowerrc permet la configuration.

  • Frameworks
  • Bibliothèques
  • ...
    bower init  # Créer un fichier bower.json
    bower install  # Installe les dépendances du projet
    bower install angular  # Installe un paquet
    bower install --save angular  # Installe un paquet et l'ajoute aux dépendances
    bower install --save-dev angular  # Installe un paquet et l'ajoute aux dépendances de développements
    bower install git://github.com/user/package.git
    bower install http://example.com/script.js
    

Paquets

Notes

Voir le fichier bower.json et .bowerrc d'angular-seed.

Builder son projet avec Grunt

Grunt est une application Node.js permettant d'automatiser des taches. Il se base sur un système de plugins permettant une gestion souple des taches à effectuer.

  • concat
  • uglify
  • watch
  • ...
    npm install -g grunt-cli
    npm install --save-dev grunt grunt-contrib-concat grunt-contrib-uglify grunt-contrib-watch
    

Les taches sont enregistré dans un fichier Gruntfile.js.

Notes

Builder son projet avec Grunt - Gruntfile.js

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      build: {
        src: ['app/**/*.js', 'app/bower_components/angular/angular.min.js'],
        dest: 'app/app.js',
      }
    },
    uglify: {
      build: {
        src: 'src/app.js',
        dest: 'build/app.min.js'
      }
    },
    watch: {
      build: {
        files: ['app/**/*.js'],
        tasks: ['default'],
      }
    }
  });

  // [...]

Notes

Définition des taches.

Builder son projet avec Grunt - Gruntfile.js

  // [...]

  // Load the plugins.
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Default task(s).
  grunt.registerTask('default', ['concat', 'uglify']);
};

Notes

Chargement des plugins + enregistrement des taches (dont la tache 'default').

Builder son projet avec Grunt - Lancer les taches

grunt  # Effectue la tache "default"
grunt concat  # Effectue toute les taches du plugin "concat"
grunt concat:build  # Effectue uniquement la tache "build" de "concat"
grunt watch  # Effectue la tache watch : surveille les changements

Notes

Builder son projet avec Gulp

Gulp est également un automatiseur de tache et fonctionne également sur un système de plugins.

  • Effectue les taches en parallèles.
  • Syntaxe un peu plus logique.
  • Sépare les taches véritablement plutot que de devoir les concentrer par plugin.

Les taches sont enregistré dans un fichier gulpfile.js.

Gulp

Notes

Builder son projet avec Gulp - Gulpfile.js

var gulp = require('gulp');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');

gulp.task('js', function () {
  return gulp.src(['app/**/*.js',
                   'app/bower_components/angular/angular.min.js'])
    .pipe(concat('app/app.js'))
    .pipe(gulp.dest('./app/'))
    .pipe(uglify())
    .pipe(rename('app.min.js'))
    .pipe(gulp.dest('./app/'));
});

gulp.task('default', ['js']);

gulp.task('watch', function () {
  gulp.watch(['./app/**/*.js'], ['js']);
});

Notes

TP - Création d'une TODO-list - 11

  • Installer Font Awesome en utilisant Bower.
    • Ajouter le également au fichier bower.json (--save).
  • L'inclure dans l'application.
  • Ajouter quelques icones.
    • http://fortawesome.github.io/Font-Awesome/examples/
  • Automatiser la minification de tout les fichiers JavaScript en utilisant Grunt puis gulp.
    • Ajouter une tache permettant de surveiller la modification des fichiers JavaScript pour minifier automatiquement.
    • N'oublier pas de modifier les fichiers JavaScript inclus dans votre index.html. Il ne doit rester que le fichier minifié.
  • (Notez qu'il est également possible d'automatiser la minification des fichiers CSS).

Notes

Yeoman

Yeoman facilite la création d'un projet et des différents composants.

npm install -g yo
yo

Yeoman

Notes

Yeoman - Générateurs

  • Permet de générer un projet avec un workflow particulier.
    • angular-generator
      • Bower + Grunt + Angular
    • generator-gulp-angular
      • Bower + Gulp + Angular
  • Installer un générateur :
    yo
    > Install a generator
    # ou
    npm install -g angular-generator
    

Liste de générateurs

Notes

Yeoman - Création du projet

mkdir myapp
cd myapp
yo
> Run the Angular generator
# ou
yo angular
grunt serve
grunt test

Exemple angular.js

Notes

Yeoman - Création des composants

yo --help
yo angular:route myRoute
yo angular:controller myController
yo angular:directive myDirective
yo angular:filter myFilter
yo angular:view myView
yo angular:service myService
yo angular:factory myService
yo angular:value myService
yo angular:constant myService

Notes

Yeoman - Mise en production

grunt build
ls dist

Notes

TP - Création d'une application avec Yeoman

  • Générer un nouveau projet avec Yeoman.
  • Essayer de reproduire l'application ToDo en utilisant les différents générateur.

Notes

Méthodes utiles - JavaScript

console.log();
console.table();
debugger;

On va aussi pouvoir mettre des breakpoints directement dans la console de debug de différente manières.

Chrome tips and tricks

Notes

Méthodes utiles - AngularJS

Récuperer l'élément angular

var rootEle = document.querySelector("html");
var ele = angular.element(rootEle);
// Ou bien, avec l'inspecteur
var ele = angular.element($0);

L'utiliser

ele.scope();
ele.controller();
ele.inheritedData();

Notes

Batarang

Extension Chrome permettant d'inspecter :

  • Les modèles ($scope).
  • Les performances.
  • Les dépendances des services entre eux.

Batarang

Notes

TP - Création d'une TODO-list - 12

  • Ajouter des console.log() pour afficher les taches à leur création.
  • Utiliser Batarang pour observer les différents scopes.

Notes

Modules indispensables

Notes

Internationalisation - angular-translate

Fichier JS :

app = angular.module('myApp', ['pascalprecht.translate']);

app.config(function($translateProvider){
  $translateProvider.translations('en', {
    WELCOME: 'Welcome',
  });
  $translateProvider.translations('fr', {
    WELCOME: 'Bienvenue',
  });
  $translateProvider.preferredLanguage('fr');
});
app.controller('TranslateController', function($translate, $scope){
  $scope.changeLanguage = function(lang) {
    $translate.uses(lang);
  };
});

Fichier HTML :

<h1>{{ 'WELCOME' | translate }}</h1>
<h1 translate>WELCOME</h1>
<div ng-controller="TranslateController">
  <button ng-click="changeLanguage('en')">English</button>
  <button ng-click="changeLanguage('fr')">Français</button>
</div>

Notes

Fournit un filtre et une directive translate. Les traductions sont en JSON. Peu pratique pour des applications complexes.

Internationalisation - angular-translate - Loaders

angular-translate-loader-url

app.config(function($translateProvider){
  $translateProvider.useUrlLoader('/locales/translations.json');
  $translateProvider.preferredLanguage('fr');
  // Fichier '/locales/tranlsations.json?lang=fr'
});

angular-translate-loader-static-files

app.config(function($translateProvider){
  $translateProvider.useStaticFilesLoader({
    prefix: '/locales/',
    suffix: '.json',
  });
  $translateProvider.preferredLanguage('fr');
  // Fichier '/locales/fr.json'
});

Notes

Toujours peu pratique pour une personne non technique.

Internationalisation - angular-gettext

Fichier JS :

app = angular.module('myApp', ['gettext']);

app.run(function(gettextCatalog){
  gettextCatalog.setCurrentLanguage('fr');
  // Vérifier que toutes les traductions soit présentes.
  // Les éléments non traduits auront "[MISSING]:" de préfixés.
  gettextCatalog.debug = true;
});

app.controller('TranslateController', function($scope, gettextCatalog){
  $scope.changeLanguage = function(lang) {
    gettextCatalog.setCurrentLanguage(lang);
  };
});

app.controller('ExampleController', function($scope, gettextCatalog){
  $scope.persons = 2;
  $scope.name = "Foo";
});

Notes

Un fichier .js supplémentaire contenant les traduction est ajouté à l'application. Nous verrons plus loin comment générer ce fichier JS.

Internationalisation - angular-gettext

Fichier HTML :

<div ng-controller="ExampleController">
  <h1 translate>Welcome</h1>
  <input type="text" placeholder="{{ 'Username' | translate }}" />
  <div translate translate-n="personsCount"
       translate-plural="{{$count}} persons">One person</div>
  <div translate-comment="Hello message" translate>Hello {{ name }}</div>
</div>

<div ng-controller="TranslateController">
  <button ng-click="changeLanguage('en')">English</button>
  <button ng-click="changeLanguage('fr')">Français</button>
</div>

Notes

Filtre et directive disponible. Permet la traduction des pluriels. Permet la traduction avec variables.

Internationalisation - angular-gettext - Le workflow

  1. Extraction (.pot)
  2. Mise à jour du fichier de langue (.po)
  3. Compilation (.js)

Notes

Extraction des textes à traduires. Intégration de ces textes dans le fichier de traduction. Traduction. Compilation.

Internationalisation - angular-gettext - Extraction

grunt-angular-gettext

nggettext_extract: {
  pot: {
    files: {
      'po/template.pot': ['src/views/*.html']
    }
  },
},

gulp-angular-gettext

gulp.task('pot', function () {
  return gulp.src(['src/views/*.html'])
    .pipe(gettext.extract('template.pot'))
    .pipe(gulp.dest('po'));
});

Notes

Internationalisation - angular-gettext - Traduction

poedit permet de modifier les fichiers .po.

Créer un fichier de traduction .po à partir du .pot

File/New Catalog from POT File...

Notes

Internationalisation - angular-gettext - Traduction

Mettre à jour un fichier de traduction .po à partir du .pot

Catalog/Update from POT File...

Traduire le fichier de traduction .po

Puis sauvegarder.

Notes

Internationalisation - angular-gettext - Compilation

grunt-angular-gettext

nggettext_compile: {
  all: {
    files: {
      'src/js/translations.js': ['po/*.po']
    }
  },
},

gulp-angular-gettext

gulp.task('po', function () {
  return gulp.src(['po/*.po'])
    .pipe(gettext.compile())
    .pipe(gulp.dest('src/js/'));
});

Notes

Pensez à inclure le fichier JS ainsi créer dans l'application.

TP - Création d'une ToDo List - 13

  • Traduire l'application en utilisant angular-gettext.

Notes

Bootstrap

Bootstrap sans jQuery et avec des directives.

angular-bootstrap

<progressbar class="progress-striped" value="22" type="warning">22%</progressbar>
<timepicker ng-model="mytime" ng-change="changed()" hour-step="hstep"
            minute-step="mstep" show-meridian="ismeridian"></timepicker>

angular-strap

<input type="text" class="form-control" size="8" ng-model="time" name="time" bs-timepicker>

Notes

Pas forcément les meme composant d'implémentés. Logique différente (directive element ou attribues).

Router - angular-ui-router

index.html

<body>
  <div ui-view></div>
  <a ui-sref="state1">State 1</a>
  <a ui-sref="state2">State 2</a>
</body>

partials/state1.html

<h1>State 1</h1>
<hr/>
<a ui-sref="state1.list">Show List</a>
<div ui-view></div>

partials/state1.list.html

<h3>List of State 1 Items</h3>
<ul>
  <li ng-repeat="item in items">{{ item }}</li>
</ul>

Notes

Permet de faire des vues dans des vues ainsi que des vues multiples sur la même page. Permet également de nommer ses vues.

Router - angular-ui-router

partials/state2.html

<h1>State 2</h1>
<hr/>
<a ui-sref="state2.list">Show List</a>
<div ui-view></div>

partials/state2.list.html

<h3>List of State 2 Things</h3>
<ul>
  <li ng-repeat="thing in things">{{ thing }}</li>
</ul>

ui-router

Notes

Router - angular-ui-router

myApp.config(function($stateProvider, $urlRouterProvider) {
  $urlRouterProvider.otherwise("/state1");
  $stateProvider
    .state('state1', {
      url: "/state1",
      templateUrl: "partials/state1.html"
    })
    .state('state1.list', {
      url: "/list",
      templateUrl: "partials/state1.list.html",
      controller: function($scope) {
        $scope.items = ["A", "List", "Of", "Items"];
      }
    })
    .state('state2', {
      url: "/state2",
      templateUrl: "partials/state2.html"
    })
    .state('state2.list', {
      url: "/list",
      templateUrl: "partials/state2.list.html",
      controller: function($scope) {
        $scope.things = ["A", "Set", "Of", "Things"];
      }
  });
});

Notes

Router - angular-ui-router - Vues multiples

Fichier HTML :

<body>
  <div ui-view="viewA"></div>
  <div ui-view="viewB"></div>
  <a ui-sref="route1">Route 1</a>
  <a ui-sref="route2">Route 2</a>
</body>

Notes

Router - angular-ui-router - Vues multiples

Fichier JS :

myApp.config(function($stateProvider) {
  $stateProvider
    .state('index', {
      url: "",
      views: {
        "viewA": { template: "index.viewA" },
        "viewB": { template: "index.viewB" }
      }
    })
    .state('route1', {
      url: "/route1",
      views: {
        "viewA": { template: "route1.viewA" },
        "viewB": { template: "route1.viewB" }
      }
    })
    .state('route2', {
      url: "/route2",
      views: {
        "viewA": { template: "route2.viewA" },
        "viewB": { template: "route2.viewB" }
      }
  });
});

Notes

TP - Création d'une ToDo List - 14

  • Modifier l'application TODO pour avoir les deux vues sur la meme page.

Notes

Aller plus loin

Notes

Dirty Checking

Surveille les modifications de variables et les propages dans l'application.

  • La boucle "$digest"
    • $watch
    • $evalAsync

Notes

Dirty Checking

$watch

En HTML :

<input ng-model="name" type="text" />

Ou en JS :

$scope.name = 'Toto';
var unregister = $scope.$watch('name', function(newVal, oldVal){
  console.log('name changed : '+ oldVal +' => '+ newVal);
});
// Remove the $watch
unregister();

$evalAsync

Execute une fonction plus tard.

$scope.$evalAsync(function(){
  console.log('evalAsync');
});

Notes

Astuces

angular.foreach

angular.forEach([1, 2, 3, 4], function(value){
  console.log(value);
});
angular.forEach({firstname: 'Foo', lastname: 'Bar'}, function(value, key){
  console.log(key +' = '+ value);
});

angular.fromJson / angular.toJson

var json = angular.toJson({firstname: 'Foo', lastname: 'Bar'});
var obj = angular.fromJson("{firstname: 'Foo', lastname: 'Bar'}");

Notes

Astuces

angular.is*

  • Array
  • Date
  • Defined
  • Element
  • Function
  • Number
  • Object
  • String
  • Undefined
    if (angular.isArray([1, 2, 3])) {
      console.log('OK !');
    }
    

Notes

Astuces

angular.copy

var obj = {firstname: 'Foo', lastname: 'Bar'};
var newObj = angular.copy(obj);
newObj.name = "Toto";
obj.name == "Foo"; // OK

Désactiver les infos de débug

Infos nécessaire pour Protractor ou Batarang. À n'utiliser qu'en production.

app.config(['$compileProvider', function ($compileProvider) {
  $compileProvider.debugInfoEnabled(false);
}]);

// Réactiver avec :
angular.reloadWithDebugInfo();

Notes

Extras

Notes

One-way binding : {{ ::expression }}