web-dev-qa-db-fra.com

Comment savoir quels champs de saisie ont été modifiés dans AngularJS

Je travaille sur un formulaire d'édition (user.html) qui transfère les données à une API, mais j'aimerais éviter de remplacer toutes les données du formulaire. Je voudrais mettre juste les éléments modifiés.

J'ai constaté l'utilisation de sales et de vierges lors de l'utilisation de formulaires, mais cela s'applique à tout changement de formulaire. J'ai aussi vu l'utilisation de ng-change, mais je ne veux pas déclencher d'action sur une modification d'un élément, mais simplement que l'élément modifié doit être inclus dans le PUT.

Quelqu'un a trouvé un moyen de ne désigner que les champs de saisie qui ont été modifiés?

35
brock

Si vous mettez l'entrée dans une variable form avec un attribut name, puis que vous lui attribuez un attribut name, vous pouvez également accéder à la propriété $pristine de l'entrée.

<div ng-controller="MyController">
  <form name="myForm">
    <input type="text" name="first" ng-model="firstName">
    <input type="text" name="last" ng-model="lastName">
  </form>
</div>
app.controller('MyController', function($scope) {
  // Here you have access to the inputs' `$pristine` property
  console.log($scope.myForm.first.$pristine);
  console.log($scope.myForm.last.$pristine);
});

Vous pouvez utiliser $scope.myForm.$pristine pour voir si les champs ont été modifiés et la propriété $pristine dans la propriété de chaque entrée du formulaire pour voir si cette entrée a été modifiée. Vous pouvez même effectuer une itération sur l'objet myForm (les objets des champs autres que les champs de saisie ont un préfixe $):

angular.forEach($scope.myForm, function(value, key) {
  if(key[0] == '$') return;
  console.log(key, value.$pristine)
});
// first, true
// last, false
53
Michelle Tilley

Je constate souvent que vous souhaiterez davantage de fonctionnalités pour permettre aux utilisateurs de mettre à jour les paramètres/informations. Tels que la possibilité de réinitialiser les informations ou d'annuler l'édition et de revenir en arrière. Je sais que cela ne faisait pas partie de la demande, mais quand vous considérez cela, cela facilite les choses.

Vous stockez les valeurs enregistrées et avez également les valeurs modifiées. Vous pouvez rétablir les valeurs enregistrées car elles ne changent pas. Ensuite, vous pouvez comparer le 2 pour déterminer ce qui a changé.

Exemple de travail: http://jsfiddle.net/TheSharpieOne/nJqTX/2/

Consultez le journal de la console pour voir ce qui a changé lorsque vous soumettez le formulaire dans l'exemple. C'est un objet que vous pouvez facilement envoyer via PUT.

function myCtrl($scope) {
    $scope.user = {
        firstName: "John",
        lastName: "Smith",
        email: "[email protected]"
    };
    $scope.reset = function () {
        angular.copy($scope.user, $scope.edit);
    };
    $scope.submitForm = function(){
        console.log(findDiff($scope.user, $scope.edit));
        // do w/e to save, then update the user to match the edit
        angular.copy($scope.edit, $scope.user);
    };

    function findDiff(original, edited){
        var diff = {}
        for(var key in original){
            if(original[key] !== edited[key])
                diff[key] = edited[key];
        }
        return diff;
    }
}

Remarque: findDiff est simple, en supposant que les deux objets ont les mêmes clés et que seules les valeurs ont été modifiées. Nous copions les objets pour qu’ils ne deviennent pas 2 références au même objet, mais bien 2 objets.

19
TheSharpieOne

si vous utilisiez la réponse de TheSharpieOne, vous pouvez vérifier l’égalité à l’aide de angular.equals au lieu de "===", sinon cela ne fonctionnera pas pour les tableaux.

function findDiff(original, edited){
  var diff = {}
    for(var key in original){
      if(!angular.equals(original[key], edited[key]))
        diff[key] = edited[key];
    }
    return diff;
}
8
ARN

Vous pouvez utiliser $scope.$watch('scopeVariable', function(oldValue, newValue)...) et créer un objet contenant uniquement newValues qui diffèrent de oldValues.

Voici un lien link aux documents angulaires concernant $ watch.

2
Sergiu Paraschiv

Construire à partir des réponses de ARN et TheSharpieOne. Si vous utilisez un trait de soulignement dans votre projet, vous pouvez adopter cette approche pour rechercher les différences dans les tableaux d'objets.

function findDiff(original, edited){
    _.filter(original, function(obj){ return !_.findWhere(edited, obj); });
}
1
Joe Komputer

Un moyen simple de récupérer un objet uniquement avec les valeurs modifiées lors de l'événement submit:

var dirtyInput = $('#myForm .ng-dirty');
var change = {};

for (var i = 0; i < dirtyInput.length; i++) {
  change[dirtyInput[i].name] = dirtyInput[i].value;
}
0
Bryan Dartout

Ajouter plus à La réponse de TheSharpieOne . La différence entre l'original et l'édition peut également être due à l'ajout de nouveaux champs dans l'objet édité. D’où vérification supplémentaire pour le même 

function findDiff(original, edited){
    var diff = {}
    for(var key in original){
      if(!angular.equals(original[key], edited[key]))
        diff[key] = edited[key];
    }
    for(var key in edited){
      if(!angular.equals(original[key], edited[key]))
        diff[key] = edited[key];
    }

    return diff;
}
0
Venkat Kotra