Il y a 9 ans -
Temps de lecture 6 minutes
[DevoxxFR] Au secours, mon code AngularJS est pourri !
La session "Au secours, mon code AngularJS est pourri!" était présentée par Thierry Chatel. L’idée de la présentation était de montrer comment créer une application qui reste maîtrisable et maintenable plusieurs mois après sa création.
Thierry Chatel commence la session par quelques conseils généraux relatifs à l’éco-système AngularJS :
- Il met tout d’abord en garde contre l’intégration aveugle de modules AngularJS dont la qualité peut être très variable. Il faut donc faire attention aux modules que nous intégrons à nos applications.
- Ensuite, il nous conseille d’éviter les optimisations prématurées, voire les optimisations tout court. Il est préférable d’écrire du code simple qui rendra le code plus maintenable. Dans la quasi-totalité des cas, il n’y a pas d’intérêt à optimiser. On ne gagne rien, à part à perdre du temps sur la maintenance du code optimisé. Il explique par exemple qu’il ne faut pas hésiter avec AngularJS à binder sur le résultat d’une fonction.
- Il est préférable de travailler sur des modèles de données adaptés à votre application : ViewModel, pas uniquement du JSON renvoyé par les services de vos backends. Ainsi, il ne faut pas se limiter systématiquement à faire des bindings sur le JSON reçu, mais également sur des domaine adaptés. Il y a donc intérêt à travailler avec un vrai modèle objet.
-
De même, il ne faut pas hésiter à faire remonter un service ou bien une façade dans le scope, et de s’appuyer dessus dans les templates. il n’y a pas de contre-indication, ce n’est pas une hérésie.
Comment organiser la structure d’une grosse application ?
Pour commencer, une bonne façon est d’avoir un découpage fonctionnel et arborescent. C’est seulement au plus bas niveau qu’on mettra des modules avec des fichiers d’un différent type :
front / profiles/ repositories/ activity/ contributions/ back/ statistics/ common/
Une bonne pratique associée à la gestion des modules est d’avoir un fichier JS par module.
Et le détail d’un découpage au niveau d’une fonctionnalité :
front/ front.js profiles/ profiles.js profiles-controller.js profiles-service.js profiles-directive.js repositories/ repositories.js
Si vous avez des modules de type "common", rien ne vous empêche de les organiser de la même façon:
common/ common.js common-service.js common-filter.js common-directive.js
Les routes
Pour une bonne gestion des routes, il est préférable d’avoir un fichier de déclaration de vos routes pour chacune de vos fonctionnalités. Cela vous aidera à rendre votre code plus modulable.
Vous pouvez par ailleurs ajouter des données à la définition de vos routes et les récupérer via la variable : $route.current, ce qui peut se révéler bien pratique.
Contrôleurs
Les contrôleurs servent à initialiser le scope et rien d’autre : publier des données dans le scope, afin de les mettre à disposition pour vos templates. Il ne faut pas les utiliser pour faire du traitement.
Le contrôleur est le lien entre les services et le scope. Il doit rester léger.
Vous pouvez par ailleurs découper vos contrôleurs pour gérer des portions de vue. Par exemple, il est intéressant de créer des contrôleurs sur des scopes répétés :
<ul> <li> ng-repeat="..." ng-controller="itemController">...</li> </ul>
Les services
Le service est un élément central, c’est là qu’on y code l’essentiel d’une application AngularJS.
Pour chaque fonctionnalité d’une application, on doit avoir un service isolé : rien qu’une fonctionnalité, mais dans son intégralité. Il ne faut pas intégrer de traitement dans les contrôleurs, tout comme il ne faut pas intégrer des règles métier dans les templates.
Par exemple, éviter de coder en dur une règle métier conditionnant le style d’affichage d’un élément :
ng-class="{alert: quantity(row) >= 100}"
Encapsuler plutôt la règle dans un service :
ng-class="{alert: orderSrv.isAlert(row)}"
Les services permettent de conserver les données : un service Angular gère les données comme les traitements.
Conseils complémentaires : lorsque vous travaillez avec des services asynchrones, il est préférable de renvoyer des promesses. De même, si vous voulez obtenir une structure efficace de votre application, il faut découper les services en couches.
Par exemple, pour gérer vos erreurs et notifications, vous pouvez découper vos service de la façon suivante :
- Un intercepteur $http
- Surcharge du service $exceptionhandler
- Un service pour les erreurs
- Un service de log serveur
- Un service de notification
Les promesses
Un gros atout des promesses, c’est qu’elles permettent d’utiliser le même code pour du code synchrone et asynchrone. Le secret pour faire du code simple avec des promesses, est de n’utiliser que des promesses (jamais les résultats !). On stocke des promesses et jamais autre chose. En cas d’échec, on envoie une promesse en erreur ou bien on lance une exception.
Les filtres
Il ne faut jamais modifier les données reçues en entrée. De même, il faut éviter de prendre des noms de propriétés dans les filtres. Il faut plutôt passer par des expressions :
users | orderBy: ‘profile.name’:false
Directives
Lors du développement de directives, il faut privilégier les bindings aux manipulations de DOM (à réserver aux nécessités). L’objectif est de s’appuyer sur le HTML plutôt que de le remplacer (Syndrome JSF).
Les directives ont pour but d’ajouter un comportement plutôt que de générer du code …
Les attributs de la balise HTML de la directive sont l’interface de la directive.
Tests
Est-ce qu’il faut soigner le code des tests ? Oui, il faut également le maintenir. Et c’est là également que cela va coûter cher.
Une astuce, vous pouvez imbriquer des "describe" pour factoriser dans un "beforeEach".
Avec Protractor: factoriser des ElementFinder et des fonctions.
Conclusion
Pour faire simple, ce qu’il faut retenir :
- Il faut partir du HTML,
- Profiter de la souplesse du JS, et
- Appliquer les bonnes pratiques de programmation objet.
Pour continuer de creuser un petit peu le sujet d’AngularJS, il était possible de suivre une session sur le "Reactive Programming" présentée par Martin Gontovnikas qui en présentait les principes dans le contexte du développement d’applications AngularJS, mais ceci est une autre histoire… Pour en découvrir un peu plus en attendant les vidéos sur Parleys, vous pouvez creuser le sujet en vous rendant sur le repo GitHub du projet: https://github.com/Reactive-Extensions/rx.angular.js
Les slides de la présentation: http://www.methotic.com/thierry/devoxx-france-2014/slides.pdf
Commentaire
2 réponses pour " [DevoxxFR] Au secours, mon code AngularJS est pourri ! "
Published by Nicolas coquelet , Il y a 9 ans
Hey Alex,
bien ou bien ? ;)
C’est marrant, car on est entrain de faire notre transition html5, avec la question du choix du framework à utiliser. Depuis hier, je fais des tests avec Ember, n’ayant pas trop accroché la syntaxe d’Angular. Ton post me conforte presque dans mon choix ;) même si avec Ember c’est la même bataille : faire simple, respecter les conventions, ne pas écouter tout ce qu’il se dit sur stackoverflow ;)
Et ça vaut pour toutes les technologies !
Super post