简体   繁体   中英

AngularJS : check if a model value has changed

IS there a way to check a dirty flag on the model itself, independent of the view?

I need the angular controller to know what properties have been changed, in order to only save changed variables to server.

I have implemented logic regarding if my entire form is dirty or pristine, but that is not specific enough

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

Another not-so appealing approach is to store the initial values that every input is bound to in a separate object, then compare the current values with the initial values to know if they have changed.

I checked Monitor specific fields for pristine/dirty form state and AngularJS : $pristine for ng-check checked inputs

One option I could think of is

  1. As you get a model/object from service, create a replica of the model within the model and bind this new model to your view.

  2. Add a watch on 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] } } } } } 

You may find it easiest to store and later compare against the JSON representation of the object, rather than looping through the various properties.

See Detect unsaved data using angularjs .

The class shown below may work well for your purpose, and is easily reused across pages.

At the time you load your models, you remember their original values:

    $scope.originalValues = new OriginalValues();

    // Set the model and remember it's 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 multiple models. If you only have one ng-model the key can simply be 'model' or any other string.

The assumption is that properties starting with '$' or '_' should be ignored when looking for changes, and that new properties will not be added by the UI.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM