36

我正在处理将数据放入 API 的编辑表单(user.html),但我想避免将所有数据放入表单中。我想只放更改的项目。

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

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

4

7 回答 7

53

如果将输入放入form带有name属性的 a 中,然后为输入赋予name属性,则还可以访问输入的$pristine属性。

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

您可以使用$scope.myForm.$pristine查看是否有任何字段已更改,并$pristine使用表单上每个输入的属性来查看该输入是否已更改。您甚至可以遍历myForm对象(非输入字段对象的键以 a 为前缀$):

angular.forEach($scope.myForm, function(value, key) {
  if(key[0] == '$') return;
  console.log(key, value.$pristine)
});
// first, true
// last, false
于 2013-09-05T16:46:40.353 回答
19

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

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

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

查看控制台日志以查看在示例中提交表单时发生的变化。它是您可以通过 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;
    }
}

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

于 2013-09-05T17:38:48.040 回答
8

旧线程,但要建立在 TheSharpieOne 的答案上,您可能需要使用 angular.equals 而不是“===”来检查是否相等,否则这不适用于数组。

function findDiff(original, edited){
  var diff = {}
    for(var key in original){
      if(!angular.equals(original[key], edited[key]))
        diff[key] = edited[key];
    }
    return diff;
}
于 2015-08-31T14:44:19.470 回答
2

您可以使用$scope.$watch('scopeVariable', function(oldValue, newValue)...)和构建仅包含newValue与 s 不同oldValue的 s 的对象。

这是关于 $watch 的 Angular 文档的链接。

于 2013-09-05T16:40:24.627 回答
1

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

function findDiff(original, edited){
    _.filter(original, function(obj){ return !_.findWhere(edited, obj); });
}
于 2016-04-07T17:37:59.313 回答
0

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

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

for (var i = 0; i < dirtyInput.length; i++) {
  change[dirtyInput[i].name] = dirtyInput[i].value;
}
于 2016-11-23T14:25:36.833 回答
0

为TheSharpieOne 的答案添加更多内容。原始和编辑之间的差异也可能是由于在编辑对象中添加了新字段。因此额外检查相同

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;
}
于 2018-01-27T09:02:43.970 回答