AngularJS: check if model value has changed

Is there a way to check for a dirty flag on the model itself, regardless of the view?

I need an angular controller to find out which properties have changed so that only the changed variables are saved on the server.

I applied logic that my whole form is dirty or untouched, but this is not specific enough

I could just click the name and ng-form attribute on each input to make it recognizable as a form in the controller, but then I end up with a controller that is strongly linked to the view.

Another unattractive approach is to store the initial values ​​that each input is associated with in a separate object, and then compare the current values ​​with the initial values ​​to see if they have changed.

I have checked Monitoring certain fields for clean / dirty form state and AngularJS: $ pristine for ng-check checkboxes

+3


source to share


3 answers


One option I could think of is



  • When you get a model / object from a service, create a replica of the model in the model and bind this new model to your view.

  • Add the watch to the new model and as the model changes, use the replica to compare old and new models as follows

    var myModel = {
        property1: "Property1",
        property2: "Property2",
        array1:["1","2","3"]
    }
    var getModel = function(myModel){
       var oldData = {};
       for(var prop in myModel){
          oldData.prop = myModel[prop];
       }
       myModel.oldData = oldData;
       return myModel;
    }
    var getPropChanged = function(myModel){
      var oldData = myModel.oldData;
      for(var prop in myModel){
       if(prop !== "oldData"){
        if(myModel[prop] !== oldData[prop]){
            return{
                propChanged: prop,
                oldValue:oldData[prop],
                newValue:myModel[prop]
            }
          }
        }
      }
    }
    
          

+2


source


You may find it easiest to store it and then compare to the JSON representation of the object rather than iterating over different properties.



See Detecting unsaved data with angle symbols .

0


source


The class shown below might work well for your purpose and can be easily reused across different pages.

When loading your models, you remember their original values:

    $scope.originalValues = new OriginalValues();

    // Set the model and remember it value
    $scope.someobject = ...
    var key = 'type-' + $scope.someobject.some_unique_key;
    $scope.originalValues.remember(key, $scope.someobject);

      

Later you can determine if it needs to be saved using:

    var key = 'type-' + $scope.someobject.some_unique_key;
    if ($scope.originalValues.changed(key, $scope.someobject)) {
       // Save someobject
       ...
    }

      

The key allows you to remember the original values ​​for several models. If you only have one ng model, the key can simply be "model" or any other string.

It is assumed that properties beginning with '$' or '_' should be ignored when looking for changes and that new properties will not be added by the user interface.

Here's the class definition:

function OriginalValues() {
    var hashtable = [ ]; // name -> json

    return {

      // Remember an object returned by the API
      remember: function(key, object) {
        // Create a clone, without system properties.
        var newobj = { };
        for (var property in object) {
          if (object.hasOwnProperty(property) && !property.startsWith('_') && !property.startsWith('$')) {
            newobj[property] = object[property];
          }
        }
        hashtable[key] = newobj;
      },// remember

      // See if this object matches the original
      changed: function(key, object) {
        if (!object) {
          return false; // Object does not exist
        }

        var original = hashtable[key];
        if (!original) {
          return true; // New object
        }

        // Compare against the original
        for (var property in original) {
          var changed = false;
          if (object[property] !== original[property]) {
            return true; // Property has changed
          }
        }
        return false;
      }// changed

    }; // returned object
  } // OriginalValues

      

0


source







All Articles