javascript AngularJS:检查模型值是否已更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27000366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 06:48:11  来源:igfitidea点击:

AngularJS : check if a model value has changed

javascriptangularjs

提问by CodeToad

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.

我可以在每个输入上添加一个名称和 ng-form 属性,使其可识别为控制器中的表单,但最终我得到了一个与视图强耦合的控制器。

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 stateand AngularJS : $pristine for ng-check checked inputs

我检查了监视器特定字段的原始/脏表单状态AngularJS : $pristine for ng-check 检查输入

采纳答案by Mothupally

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]
            }
          }
        }
      }
    }
    
  1. 当您从服务中获取模型/对象时,在模型中创建模型的副本并将这个新模型绑定到您的视图。

  2. 在新Model上加一块手表,随着型号的变化,用复刻品对比新旧型号如下

    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]
            }
          }
        }
      }
    }
    

回答by Philip Callender

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

您可能会发现最容易存储并稍后与对象的 JSON 表示进行比较,而不是遍历各种属性。

See Detect unsaved data using angularjs.

请参阅使用 angularjs 检测未保存的数据

回答by Philip Callender

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.

该键允许您记住多个模型的原始值。如果您只有一个 ng-model,则键可以简单地为 'model' 或任何其他字符串。

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.

假设是在查找更改时应忽略以“$”或“_”开头的属性,并且 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