如何表示在AngularJS中哪些输入字段发生了更改

时间:2022-06-29 07:17:39

I'm working on an edit form (user.html) that PUTs data to an API, but I'd like to avoid PUTting all the data in the form. I'd like to PUT just the changed items.

我正在编写一个编辑表单(user.html),它将数据放到API中,但我希望避免将所有数据都放在表单中。我只想把更改过的项目放进去。

I've seen the use of dirty and pristine when working with forms, but this applies to any change in the form. I've also seen the use of ng-change, but I don't want to trigger an action on a change to one element, just denote that the changed element should be included in the PUT.

我看到过在处理表单时使用脏的和原始的,但是这适用于表单中的任何更改。我还看到了使用ng-change,但我不想在对一个元素的更改上触发一个操作,只是表示应该将已更改的元素包含在PUT中。

Anyone found a way to denote only the input fields that have changed?

有人找到一种方法来表示已经更改的输入字段吗?

7 个解决方案

#1


50  

If you put the input in a form with a name attribute and then give the input a name attribute, you can also access the input's $pristine property.

如果您将输入放在带有name属性的表单中,然后给输入一个name属性,您还可以访问输入的$原始属性。

<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);
});

You can use $scope.myForm.$pristine to see if any fields have changed, and the $pristine property on each input's property on the form to see if that input has changed. You can even iterate over the myForm object (non-input-field objects have keys prefixed with a $):

您可以使用scope.myForm美元。$ pure查看是否有任何字段发生了更改,以及窗体上每个输入的$ pure属性是否发生了更改。甚至可以遍历myForm对象(非输入字段对象的键前缀为$):

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

#2


19  

I often find that you will want more functionality when allowing users to update settings/information. Such as the ability to reset the information or cancel the edit and revert back. I know that was not part of the request, but when you consider this it makes other things easier.

我经常发现,当允许用户更新设置/信息时,您需要更多的功能。例如可以重置信息或取消编辑和恢复。我知道这不是请求的一部分,但当你考虑到这一点时,其他事情就会变得更容易。

You store the saved values and also have the edited values, you can reset back to the saved values as they don't change. Then you can compare the 2 to determine what changed.

您可以存储已保存的值并拥有已编辑的值,您可以重新设置为已保存的值,因为它们不会更改。然后你可以比较2来确定什么改变了。

Working Example: http://jsfiddle.net/TheSharpieOne/nJqTX/2/

工作示例:http://jsfiddle.net/TheSharpieOne/nJqTX/2/

Look at the console log to see what changed when you submit the form in the example. It is an object that you can easily send via PUT.

查看控制台日志,查看在示例中提交表单时发生了什么更改。它是一个可以通过PUT轻松发送的对象。

function myCtrl($scope) {
    $scope.user = {
        firstName: "John",
        lastName: "Smith",
        email: "john.smith@example.com"
    };
    $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;
    }
}

Note: the findDiff is simple, it assume the two objects have the same keys and only the values have changed. We copy the objects so that they do not become 2 references to the same object, but in fact 2 objects.

注意:findDiff很简单,它假设两个对象具有相同的键,并且只有值发生了变化。我们复制对象,这样它们就不会成为同一个对象的两个引用,而实际上是两个对象。

#3


7  

old thread but to build on TheSharpieOne's answer, you may want to check for equality using angular.equals instead of "===" otherwise this won't work for arrays.

旧的线程,但是要建立在这个问题的答案上,你可能要用角来检查是否相等。=而不是"==="否则对数组无效。

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

#4


2  

You can use $scope.$watch('scopeVariable', function(oldValue, newValue)...) and build an object containing only newValues that are different than oldValues.

你可以使用美元范围。$watch('scopeVariable', function(oldValue, newValue)…)并构建一个只包含与oldValues不同的新值的对象。

Here's a link to Angular docs regarding $watch.

这是关于$watch的有棱角的文档链接。

#5


0  

Building off ARN and TheSharpieOne's answers. If you are using underscore in your project you could take this approach for finding differences in arrays of objects.

建立了ARN和TheSharpieOne的答案。如果在项目中使用下划线,可以使用这种方法来查找对象数组中的差异。

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

#6


0  

A simple way to retrieve an object only with changed values on submit event:

仅在提交事件上更改值时检索对象的简单方法:

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

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

#7


0  

Adding more to TheSharpieOne's answer. The diff between original and edited could also be due to new fields added in the edited object. Hence additional check for the same

对于这个问题的答案,我们可以做更多的补充。原始和编辑之间的差异也可能是由于编辑对象中添加了新字段。因此,需要进行额外的检查

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

#1


50  

If you put the input in a form with a name attribute and then give the input a name attribute, you can also access the input's $pristine property.

如果您将输入放在带有name属性的表单中,然后给输入一个name属性,您还可以访问输入的$原始属性。

<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);
});

You can use $scope.myForm.$pristine to see if any fields have changed, and the $pristine property on each input's property on the form to see if that input has changed. You can even iterate over the myForm object (non-input-field objects have keys prefixed with a $):

您可以使用scope.myForm美元。$ pure查看是否有任何字段发生了更改,以及窗体上每个输入的$ pure属性是否发生了更改。甚至可以遍历myForm对象(非输入字段对象的键前缀为$):

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

#2


19  

I often find that you will want more functionality when allowing users to update settings/information. Such as the ability to reset the information or cancel the edit and revert back. I know that was not part of the request, but when you consider this it makes other things easier.

我经常发现,当允许用户更新设置/信息时,您需要更多的功能。例如可以重置信息或取消编辑和恢复。我知道这不是请求的一部分,但当你考虑到这一点时,其他事情就会变得更容易。

You store the saved values and also have the edited values, you can reset back to the saved values as they don't change. Then you can compare the 2 to determine what changed.

您可以存储已保存的值并拥有已编辑的值,您可以重新设置为已保存的值,因为它们不会更改。然后你可以比较2来确定什么改变了。

Working Example: http://jsfiddle.net/TheSharpieOne/nJqTX/2/

工作示例:http://jsfiddle.net/TheSharpieOne/nJqTX/2/

Look at the console log to see what changed when you submit the form in the example. It is an object that you can easily send via PUT.

查看控制台日志,查看在示例中提交表单时发生了什么更改。它是一个可以通过PUT轻松发送的对象。

function myCtrl($scope) {
    $scope.user = {
        firstName: "John",
        lastName: "Smith",
        email: "john.smith@example.com"
    };
    $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;
    }
}

Note: the findDiff is simple, it assume the two objects have the same keys and only the values have changed. We copy the objects so that they do not become 2 references to the same object, but in fact 2 objects.

注意:findDiff很简单,它假设两个对象具有相同的键,并且只有值发生了变化。我们复制对象,这样它们就不会成为同一个对象的两个引用,而实际上是两个对象。

#3


7  

old thread but to build on TheSharpieOne's answer, you may want to check for equality using angular.equals instead of "===" otherwise this won't work for arrays.

旧的线程,但是要建立在这个问题的答案上,你可能要用角来检查是否相等。=而不是"==="否则对数组无效。

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

#4


2  

You can use $scope.$watch('scopeVariable', function(oldValue, newValue)...) and build an object containing only newValues that are different than oldValues.

你可以使用美元范围。$watch('scopeVariable', function(oldValue, newValue)…)并构建一个只包含与oldValues不同的新值的对象。

Here's a link to Angular docs regarding $watch.

这是关于$watch的有棱角的文档链接。

#5


0  

Building off ARN and TheSharpieOne's answers. If you are using underscore in your project you could take this approach for finding differences in arrays of objects.

建立了ARN和TheSharpieOne的答案。如果在项目中使用下划线,可以使用这种方法来查找对象数组中的差异。

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

#6


0  

A simple way to retrieve an object only with changed values on submit event:

仅在提交事件上更改值时检索对象的简单方法:

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

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

#7


0  

Adding more to TheSharpieOne's answer. The diff between original and edited could also be due to new fields added in the edited object. Hence additional check for the same

对于这个问题的答案,我们可以做更多的补充。原始和编辑之间的差异也可能是由于编辑对象中添加了新字段。因此,需要进行额外的检查

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