如何表示AngularJS中哪些输入字段已更改

bro*_*ock 36 angularjs angularjs-ng-change

我正在编写一个将数据PUT到API的编辑表单(user.html),但我想避免PUTting表单中的所有数据.我想把改变的项目PUT.

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

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

Mic*_*ley 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>
Run Code Online (Sandbox Code Playgroud)
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);
});
Run Code Online (Sandbox Code Playgroud)

您可以使用$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
Run Code Online (Sandbox Code Playgroud)

  • 假设用户进入页面并且`firstName`字段为空.`$ scope.firstName.$ pristine`此时设置为`true`.然后用户输入"foo".`$ scope.firstName.$ pristine`现在设置为`false`.然后用户退格三次以使输入为空,就像它最初一样.`$ scope.firstName.$ pristine`继续设置为`false`. (4认同)
  • @WalterRoman这是对的.`$ pristine`在[docs](https://docs.angularjs.org/api/ng/type/form.FormController)中定义为:"如果用户尚未与表单进行交互,则为True" (3认同)

The*_*One 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:findDiff很简单,它假设两个对象具有相同的键,只有值已更改.我们复制对象,使它们不会成为对同一对象的2个引用,实际上是2个对象.

  • 您可以使用`angular.copy(source,dest)`而不是编写自己的`clone`函数.我确实喜欢你的方法. (8认同)
  • 我忘记了.给你好+1先生.(编辑回答反射这个) (2认同)

小智 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;
}
Run Code Online (Sandbox Code Playgroud)