De l'utilisation d'AngularJS avec un formulaire qui sera soumis au serveur
Tout d'abord, il faut savoir qu'AngularJS bloque automatiquement la soumission "classique" d'un formulaire sous son joug , sauf si celui-ci dispose d'un attribut
action
. Mais qu'en est-il si vous souhaitez déléguer la gestion du formulaire à AngularJS sous certaines conditions, ou plutôt jusqu'à un certain point ? Je pense notamment à la validation, un point que le framework gère très bien, mais pour lequel il peut être sympathique d'avoir un moyen de lui demander de nous rendre la main quand sa tâche est accomplie.Il y a plusieurs solutions envisageables ; de mon côté, je privilégie la suivante, qui est limpide et facilement réutilisable. Voici la balise d'ouverture du formulaire :
<form method="POST" data-target="/my-action.html" data-ng-submit="submit()">
Notez l'attribut personnalisé
data-target
qui vient remplacer l'action
, ainsi que le listener pour l'évènement de soumission. Voici la méthode appelée par ce dernier, qui pour notre exemple se situe directement dans notre contrôleur :$scope.submit = function() {
var $form = $element.find('form'); // à ajuster
if (/* insérez ici vos conditions */) {
$form.attr('action', $form.data('target')).submit(); // le formulaire sera désormais soumis de manière classique
}
};
Simplissime, non ? D'aucuns souligneront que procéder ainsi équivaut à un viol potentiel (pour toi, Google) du principe de base d'AngularJS qui interdit toute manipulation du DOM dans un contrôleur. À mes yeux, il s'agit plus d'un tour de passe-passe qu'autre chose, mais c'est vous qui voyez.
...d'autant que transformer ce code en une directive ne représente pas un obstacle insurmontable.
moi du Futur
Un autre point qui peut être surprenant lors des premiers pas avec AngularJS concerne la façon dont celui-ci remplit les
select
. En effet, aucun contrôle n'est possible sur l'attribut value
des éléments option
générés par la directive correspondante, à savoir ngOptions
. Plutôt que de chercher un chemin de traverse compliqué, faisons preuve d'astuce :<!-- Ne faites pas : -->
<select name="my_key" ng-model="myModel" ng-options="select o.label for o in myOptions"></select>
<!-- Mais faites plutôt : -->
<select ng-model="myModel" ng-options="select o.label for o in myOptions"></select>
<input type="hidden" name="my_key" value="{{ myModel }}" />
Ceci vous permet de gérer indépendamment le
select
et la valeur correspondante qui sera envoyée au serveur.