vendredi 21 février 2014

Drupal + AngularJS : l'ultime solution de theming pour Drupal ?

Customiser le code HTML créé par Drupal et ses modules est sans doute l'un des points les plus difficiles à comprendre. Les solutions proposées pour tenter de faciliter cette tâche sont nombreuses : Starter thèmes, modules type Panels ou  Display Suite, modules d'intégration de bibliothèques JavaScript, la liste est infinie. On passe beaucoup de temps dans la création d'un site sous Drupal à tenter de livrer un code HTML qui conviendra à l'intégrateur, qui de toute façon s'arrachera les cheveux à un moment ou un autre.

AngularJS est un framework Javascript qui adapte et étend le HTML grâce à des directives qu'on y inclut. Mes premiers pas avec AngularJS m'ont donné à penser qu'il pourrait bien être complémentaire de Drupal. Parlons de ces premiers pas justement, la communauté AngularJS propose un tutoriel pour débuter qui permet de créer une application Phonecat qui affiche des informations techniques à propos de téléphones portables.

Je vous propose donc de modifier cette application pour qu'elle récupère ses informations depuis Drupal via des web services. Drupal servirait alors uniquement de backoffice à l'application AngularJS, chose que ce CMS fait très bien.

Fonctionnement


L'idée est donc la suivante :


A partir de Drupal je vais créer un nouveau type de contenu classiquement qui générera des nodes. La liste de ces nodes sera créée via le module Views. Ensuite, la vue et les nodes seront exposés via des webservices REST grâce au module Services.

Côté client, j'utiliserai $resource d'AngularJS pour les accès à ces services REST, et les données pourront être exploitées par les contrôleurs et présentées par les templates  de l'application.

jeudi 31 octobre 2013

Scope isolé dans les directives AngularJS


Second sujet que j'ai traité au Meetup chez Google, il s'agit des scopes isolés dans les directives.  Les slides se trouvent ici, et une vidéo a été mise en ligne là ; mon intervention commence par un sujet sur l'usage des services, et celui-ci est à la suite.

Le scope isolé est un outil bien pratique mis à notre disposition par AngularJS pour faciliter la création de widgets. Mais il ne faut pas l'utiliser n'importe quand, ni en faire n'importe quoi.


L'arbre des scopes


Les scopes d'AngularJS sont des objets qui servent de contexte d'évaluation des expressions contenues dans les templates.

Ils forment un arbre, dont la racine est le seul scope de l'application qui est aussi publié comme un service, sous le nom $rootScope. Ce $rootScope est associé à l'élément contenant toute l'application AngularJS, celui sur lequel on met la directive ngApp : ça peut être l'élément <html> lui-même, ou le <body>, ou un <div> à l'intérieur, peu importe.

samedi 26 octobre 2013

Services ou événements dans l'optique des tests

Quelques réflexions complémentaires à mon article sur l'usage des services, qui partent d'une question que l'on m'a posé à la fin de ma présentation au Meetup AngularJS Paris chez Google. Quelqu'un m'a demandé si les événements pouvaient être utilisés pour simplifier les tests unitaires d'un contrôleur. En limitant les injections de services en dépendances, on évite la nécessité de versions factices (mock objects) de ces services.

Cette question me turlupinait dans le trajet retour, et j'ai essayé de pousser plus loin la réflexion en explorant cette piste et diverses alternatives.

mercredi 23 octobre 2013

Usage des services AngularJS

Cet article est basé sur la présentation que j'ai faite hier au Meetup AngularJS Paris chez Google. Les slides se trouvent ici, et une vidéo a été mise en ligne là. Mais comme les slides perdent beaucoup de leur intérêt sans les explications qui vont avec, ça méritait bien un article - et même plusieurs, puisque j'ai mis deux exemples dans des articles séparés (les liens sont vers la fin). Je vais aussi en écrire un sur l'autre partie de ma présentation, sur les scopes isolés dans les directives.

S'il y a une fonctionnalité que les développeurs qui débutent sur AngularJS sous-estiment énormément, c'est bien les services. Je me rend compte régulièrement en formation ou lors d'audits que beaucoup de code pourrait être largement simplifié en utilisant plus efficacement les services. Ça n'a d'ailleurs rien d'étonnant, on commence à partir des exemples qu'on trouve sur internet, qui sont des exemples courts et n'ayant évidemment pas toute la structure d'une vraie application. Des exemples qui montrent comment ça marche, pas comment il faut faire.

Dans une application non triviale, au moins 90 % du code JavaScript devrait être dans les services. Il peut y avoir quelques directives et filtres bien sûr, dont une partie peut d'ailleurs être commune à plusieurs applications, mais ce sont les contrôleurs qui doivent être aussi réduits que possible. Un contrôleur AngularJS est juste une fonction d'initialisation du scope correspondant, et il doit essentiellement se limiter à cela : faire quelques affectations dans l'objet scope. Il ne doit pas faire de requêtes HTTP, ni des traitements sur les données, ni gérer le stockage des données.


Conserver les valeurs des critères de recherche

Comment conserver lorsque l'on change de vue à l'intérieur d'une application AngularJS des données correspondant à l'état de la vue, comme les valeurs des critères d'une recherche ?

Imaginons qu'on affiche dans une vue une liste d'objets, avec des critères permettant de faire un filtrage en local. Et sur chaque objet, un lien permet de naviguer vers une vue des détails de l'objet. Quand l'utilisateur revient sur la liste, il s'attend à la retrouver dans le même état. Ça suppose que les valeurs de filtrage saisies soient conservées.

Or si ces valeurs sont simplement dans le scope de la vue, elles seront perdues à chaque changement de vue, car le scope de l'ancienne vue est détruit par AngularJS. La solution simple pour les conserver est de les stocker dans un service.

Service AngularJS de notification

Un autre exemple de service qui peut être très utile : il s'agit d'afficher des notifications pendant quelques secondes, comme le font les applications de Google, avec un lien dans le message permettant d'annuler l'action.

C'est typiquement le genre de truc qu'on imagine compliqué, mais si on le prend bien, avec AngularJS ça s'écrit en quelques lignes - enfin sans compter le CSS qui finalement est le plus gros du boulot.

L'exemple se trouve ici sur GitHub, et il y a un lien vers la démo (c'est le même que pour l'article "Conserver les valeurs des critères de recherche"). Ajoutez des articles au panier, et quand vous en supprimez du panier, vous avez une notification avec un lien pour annuler l'action.

lundi 14 octobre 2013

Validateur pour vérifier qu'une date est postérieure à une autre

Voici un exemple de validateur spécifique, qui répond au besoin classique de vérifier que la date saisie dans un champ est postérieure à celle saisie dans un autre champ du formulaire. Typiquement, on demande de saisir une date de début et une date de fin, et on veut s'assurer qu'un utilisateur étourdi n'a pas rentré une date de fin qui précède la date de début.

L'exemple est intéressant, car il permet de voir comment valider un champ par rapport à un autre, ce qui n'est pas expliqué dans la documentation d'AngularJS.


mardi 28 mai 2013

AngularJS et performances

La plupart des applications AngularJS ne posent pas de problèmes particuliers de performances. Mais dans certains cas, où une page peut comporter un grand nombre de bindings, il va falloir y prêter attention pour éviter les ralentissements.

Les développeurs d’AngularJS ont toujours indiqué que le framework est capable de supporter sans problème 2000 bindings dans une page web, sur une machine un peu ancienne. C’est un ordre de grandeur, un ordinateur récent avec un navigateur web rapide pourra en supporter beaucoup plus sans soucis. Par contre sur un smartphone un peu poussif, il faudra être prudent pour éviter de se retrouver avec une application pénible à utiliser.

Ça peut paraître beaucoup, 2000 bindings, et dans la majorité des pages d’une application on sera très loin de cette limite théorique, mais avec un gros tableau on peut l’atteindre facilement. Dans le cas d’un tableau comportant 10 colonnes, avec un binding par colonne, il suffit d’afficher 200 lignes pour arriver aux 2000 bindings. Dans tous les cas où l’on va afficher tout un ensemble de données pour chaque élément d’une collection potentiellement grande, que ce soit sous la forme d’un tableau, d’une liste ou de toute autre façon, il va falloir faire attention.

vendredi 22 mars 2013

Communauté AngularJS France, et rédacteurs pour FrAngular

Je me suis dit qu'il manquait un espace pour les échanges et les annonces concernant AngularJS en France. Les rencontres, soirées ou conférences sur notre framework préféré commencent à se multiplier, et il devient difficile de savoir ce qui a lieu en France, ou comment avertir le public intéressé.

Du coup je viens de créer une communauté sur Google+ intitulée - après une longue réflexion - “AngularJS France”. Ce n'est peut-être pas hyper original, mais on moins on comprend assez vite de quoi il s'agit. Elle est toute fraîche, les pixels ne sont pas secs, et j'en suis encore le seul membre mais j'imagine que ça ne va pas durer. Elle n'a pas pour but de concurrencer la communauté AngularJS officielle, mais simplement de permettre de trouver facilement les infos locales sur le sujet.

jeudi 14 mars 2013

Comment aborder AngularJS ?


Si vous avez lu les articles publiés sur FrAngular qui détaillent des aspects techniques du framework, c'est que vous avez peut-être déjà dépassé le stade de l’initiation. Néanmoins, pour ceux qui découvrent AngularJS, je vais expliquer comment on peut aborder ce framework dont l’apprentissage risque de s’avérer quelque peu déroutant.

Commencez par JavaScript


JavaScript est certainement le langage le plus mal connu de ses utilisateurs de toute l’histoire de l’informatique. Combien de développeurs qui font du JavaScript ont vraiment pris le temps de l’apprendre ? On y reconnaît une syntaxe familière parce qu’on a déjà fait du Java, du C++, du PHP, enfin quelque chose qui y ressemble de très loin, et du coup en tâtonnant on arrive à écrire du code JavaScript qui fonctionne à peu près. Mais du très mauvais code JavaScript. Je suis passé par là, comme presque tout le monde.

Les concepts de JavaScript - un langage objet sans classes et avec un forte composante fonctionnelle - sont complètement différents des autres langages objets les plus répandus. Il y a plus de ressemblance entre Java, C#, Python, Ruby, et même PHP en version objet, qu’entre n’importe lequel de ces langages et JavaScript.

mardi 5 mars 2013

Le langage d'expressions d'AngularJS

Voici un article qui tient du paradoxe, puisque je vais y décrire les possibilités du langage d'expressions d'AngularJS, tout en expliquant qu'il faut les utiliser au minimum.

Avec AngularJS, on utilise des expressions pour le binding, et avec de nombreuses directives. Elles ressemblent à des expressions JavaScript, mais n'en sont pas. Elles ne sont pas directement évaluées par l'interpréteur JavaScript, mais parsées et exécutées par AngularJS. Du coup on ne peut utiliser qu'un sous-ensemble des opérateurs et des mots-clefs de JavaScript, et elles divergent aussi de JavaScript sur quelques aspects.

jeudi 28 février 2013

AngularJS, ce n'est pas pour jouer


De nombreux messages ont circulé hier sur Twitter annonçant un jeu en ligne, Bombermine, réalisé avec AngularJS. Étonnant... mais erroné. J’ai moi-même rediffusé un de ces messages, avant de regarder de plus près et de voir qu’AngularJS n’est utilisé que pour l’interface utilisateur, mais que le jeu lui-même est écrit avec GWT.

AngularJS est particulièrement efficace pour la réalisation d’application web, mais pas du tout adapté à la création de jeux.

CRUD... au sens large


Les développeurs d’AngularJS le présentent comme un framework destiné à la réalisation d’applications de type “CRUD” (Create - Read - Update - Delete), c’est-à-dire des applications web affichant des données, et permettant de les saisir ou de les modifier.

C’est effectivement le cas, si l’on ne prend pas le terme CRUD dans un sens trop restrictif, voire péjoratif. Il ne faut pas imaginer des applications réduites à l’affichage de trois pauvres formulaires, bien au contraire.

mardi 19 février 2013

Les fonctionnalités de Twig avec AngularJS: angular-twig-pack

Depuis que je travaille avec AngularJS, j'ai entendu beaucoup de gens comparer le Framework avec divers moteurs de template... Et il en existe! La liste (non-exhaustive) de wikipedia: Template_engine_(web) en est la preuve. Malheureusement, Wikipedia ne nous numérote pas ce tableau, heureusement que la console est là:

> document.querySelectorAll('.wikitable tbody tr').length
89

Bon ... Trêve de plaisanterie, passons aux choses sérieuses. Je me suis dit pourquoi ne pas prendre un moteur de template existant et créer un pack de directives, filters et services pour ne pas trop dépayser les puristes.

Kezako

Pour cet exercice, j'ai choisi le Framework Twig (uniquement car je l'ai déjà utilisé et surtout car j'adore les couleurs du site: http://twig.sensiolabs.org/).

mercredi 13 février 2013

Un outil de présentation en AngularJS

Pour une fois je ne vais pas vous détailler un aspect technique du framework, mais présenter une petite application qui peut être utile. Mais si je la présente ici, c'est bien sûr parce qu'elle est écrite avec AngularJS, et qu'il y a quelques exemples dans le code qui peuvent vous intéresser.

J'avais besoin d'un outil pour présenter des slides sur AngularJS en début de semaine prochaine : lundi 18 février à LyonJS, et mardi 19 février au Marseille JUG. Bien sûr il existe maintenant des outils pour faire des présentations en HTML avec plein d'effets spéciaux impressionnants. Mais je dois être de la vieille école, parce que j'ai toujours l'impression que ces effets qui en mettent plein la vue détournent l'attention du contenu. En fait je ne mets jamais d'animations dans mes présentations ; sans pousser aussi loin le minimalisme, je penche plus vers la “méthode Lessig”. Donc tout ce dont j'avais besoin c'était d'un outil comme ShowOff, permettant d'écrire rapidement les styles dans une syntaxe markdown.

Mais ShowOff c'est une application serveur, en Ruby, avec une liste de dépendances presque aussi longue que le bras. Du coup j'ai écrit ce week-end une version simplifiée avec AngularJS, une simple application cliente sans côté serveur. Je l'ai mise sur GitHub : angular-showoff. Il y a un lien vers la démo dans le descriptif.

vendredi 8 février 2013

Solution simple pour des formulaires avec données différées

Je ne suis pas sûr d'avoir trouvé un titre très vendeur pour cet article, mais vous y trouverez un exemple qui peut être très utile. C'est une solution hybride entre les $resource et les promises du service $q d'AngularJS. Elle est très simple à mettre en oeuvre, pour utiliser avec des formulaires travaillant sur des données chargées en asynchrone, un besoin somme toute très fréquent.

AngularJS fournit en standard le service $resource, qui permet de gérer facilement des entités chargées en asynchrone, mais il est prévu pour fonctionner avec une API serveur de type REST. Il n'est pas nécessaire que ce soit une API strictement RESTful, mais il ne faut pas qu'elle s'en éloigne trop pour que l'utilisation du service $resource soit pertinente.

lundi 4 février 2013

Drag & Drop avec AngularJS

Le drag & drop est revenu à la mode avec l'arrivée des tablettes et des smartphones. Un temps boudé par les développeurs web, il est de bon ton d'offrir de tels mécanismes dans nos applications web. A l'image de Trello et de ses fameuses colonnes, nous allons voir comment rendre des éléments html draggable et droppable.

vendredi 25 janvier 2013

Google Chart Tools avec AngularJS

Pouvoir inclure un graphique dans une application AngularJS par la simple utilisation d'une directive, l'idée est séduisante. Et bien sûr, pour respecter la philosophie du framework, le graphique doit se mettre à jour quand les données changent.



Voici un exemple de directive qui permet exactement ça, pour un graphique de type camembert, en l'occurrence le “Pie Chart” de Google Chart Tools. L'utilisation est toute simple :

<pie-chart data="chartData" title="My Daily Activities" 
           width="500" height="350"
           select="selectRow(selectedRowIndex)"></pie-chart>

Dans les attributs, on fournit simplement les données (ici "chartData", c'est le nom d'une propriété du scope, comme avec ng-bind), le titre du graphique, ses dimensions, et éventuellement une expression qui est exécutée lorsque l'utilisateur sélectionne une portion du camembert.