web-dev-qa-db-fra.com

Un clic sur un bouton dans un formulaire provoque l'actualisation de la page

J'ai un formulaire dans Angular qui contient deux balises de bouton. Un bouton envoie le formulaire sur ng-click. L’autre bouton sert uniquement à la navigation avec ng-click. Cependant, lorsque vous cliquez sur ce second bouton, AngularJS provoque un rafraîchissement de la page, ce qui déclenche un 404. J'ai laissé tomber un point d'arrêt dans la fonction et cela déclenche ma fonction. Si je fais l'une des choses suivantes, ça s'arrête:

  1. Si je supprime le ng-click, le bouton ne provoque pas d’actualisation de la page.
  2. Si je commente le code dans la fonction, cela ne provoque pas d'actualisation de la page.
  3. Si je remplace la balise de bouton par une balise d'ancrage (<a>) avec href="", le rafraîchissement ne sera alors pas activé.

La dernière solution semble être la solution la plus simple, mais pourquoi AngularJS exécute-t-il même un code après ma fonction qui provoque le rechargement de la page? On dirait un bug.

Voici le formulaire:

<form class="form-horizontal" name="myProfile" ng-switch-when="profile">
  <fieldset>
    <div class="control-group">
      <label class="control-label" for="passwordButton">Password</label>
      <div class="controls">
        <button id="passwordButton" class="secondaryButton" ng-click="showChangePassword()">Change</button>
      </div>
    </div>

    <div class="buttonBar">
      <button id="saveProfileButton" class="primaryButton" ng-click="saveUser()">Save</button>
    </div>
  </fieldset>
</form>

Voici la méthode du contrôleur:

$scope.showChangePassword = function() {
  $scope.selectedLink = "changePassword";
};
208
chubbsondubs

Si vous jetez un coup d'œil au spécification W3C , il semblerait évident d'essayer de marquer vos éléments de bouton avec type='button' lorsque vous ne souhaitez pas qu'ils soient soumis.

La chose à noter en particulier est l'endroit où il est dit

Un élément de bouton sans attribut de type spécifié représente la même chose qu'un élément de bouton dont l'attribut de type est défini sur "submit"

454
LOAS

Vous pouvez essayer d'empêcher le gestionnaire par défaut:

html:

<button ng-click="saveUser($event)">

js:

$scope.saveUser = function (event) {
  event.preventDefault();
  // your code
}
71
antage

J'utilise directive pour empêcher le comportement par défaut:

module.directive('preventDefault', function() {
    return function(scope, element, attrs) {
        angular.element(element).bind('click', function(event) {
            event.preventDefault();
            event.stopPropagation();
        });
    }
});

Et puis, en HTML:

<button class="secondaryButton" prevent-default>Secondary action</button>

Cette directive peut également être utilisée avec <a> et toutes les autres balises.

18
pleerock

Vous devez déclarer l'attribut ng-submit={expression} dans votre balise <form>.

À partir des documents ngSubmit http://docs.angularjs.org/api/ng.directive:ngSubmit

Active les expressions angular de liaison aux événements onsubmit.

De plus, cela empêche l'action par défaut (ce qui pour formulaire signifie envoyer la demande au serveur et recharger la page en cours).

18
Shane Stillwell

Vous pouvez conserver <button type="submit">, mais vous devez supprimer l'attribut action="" de <form>.

5
Anderson Ferreira

Je me demande pourquoi personne n'a proposé la solution la plus simple possible:

n'utilisez pas un <form>

A <whatever ng-form> IMHO fait un meilleur travail et sans formulaire HTML, il n'y a rien à soumettre par le navigateur lui-même. Quel est le bon comportement lorsque vous utilisez angular.

2
maaartinus

Cette réponse peut ne pas être directement liée à la question. C'est juste pour le cas où vous soumettez le formulaire en utilisant des scripts.

Selon ng-submit code

 var handleFormSubmission = function(event) {
  scope.$apply(function() {
    controller.$commitViewValue();
    controller.$setSubmitted();
  });

  event.preventDefault();
};

formElement[0].addEventListener('submit', handleFormSubmission);

Il ajoute le programme d'écoute d'envoi d'événements au formulaire. Mais le gestionnaire d'événements submit ne serait pas appelé lorsque submit est lancé en appelant form.submit (). Dans ce cas, ng-submit n'empêchera pas l'action par défaut, vous devez appeler vous-même preventDefault dans le gestionnaire ng-submit;

Pour fournir une réponse raisonnablement définitive, l'élément 5 de l'algorithme de soumission de formulaire HTML indique qu'un formulaire ne distribue un événement submit que s'il n'a pas été envoyé en appelant la méthode submit (ce qui signifie qu'il ne distribue un événement submit que s'il est soumis par un bouton ou une autre méthode implicite. méthode, par exemple en appuyant sur entrée alors que le focus est sur un élément de texte de type entrée).

Voir Le formulaire envoyé avec submit () depuis un lien ne peut pas être attrapé par le gestionnaire onsubmit

1
user1577263

Ajouter une action à votre formulaire.

<form action="#">

1
Swapnil Patwa

Le premier bouton envoie le formulaire et le second ne le fait pas

<body>
<form  ng-app="myApp" ng-controller="myCtrl" ng-submit="Sub()">
<div>
S:<input type="text" ng-model="v"><br>
<br>
<button>Submit</button>
//Dont Submit
<button type='button' ng-click="Dont()">Dont Submit</button>
</div>
</form>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.Sub=function()
{
alert('Inside Submit');
}

$scope.Dont=function()
{
$scope.v=0;
}
});
</script>

</body>
0
Amay Kulkarni