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

如何表示AngularJS中哪些输入字段已更改,angularjs,angularjs-ng-change,Angularjs,Angularjs Ng Change,我正在编写一个编辑表单(user.html),将数据放入API,但我希望避免将所有数据放入表单中。我只想把换过的东西放进去 我见过在处理表单时使用dirty和pristine,但这适用于表单中的任何更改。我也看到了ng change的用法,但我不想在对一个元素的更改上触发一个操作,只是表示更改后的元素应该包含在PUT中 有人找到了只表示已更改的输入字段的方法吗?您可以使用$scope.$watch('scopeVariable',function(oldValue,newValue)…)并构建一

我正在编写一个编辑表单(user.html),将数据放入API,但我希望避免将所有数据放入表单中。我只想把换过的东西放进去

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


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

您可以使用
$scope.$watch('scopeVariable',function(oldValue,newValue)…)
并构建一个只包含与
oldValue
不同的
newValue
的对象


这里有一个关于$watch的示例。

如果您将输入放入带有
名称
属性的
表单
,然后为输入赋予
名称
属性,您还可以访问输入的
$pristine
属性


app.controller('MyController',函数($scope){
//在这里,您可以访问输入“`pristine`属性
log($scope.myForm.first.$pristine);
log($scope.myForm.last.$pristine);
});
您可以使用
$scope.myForm.$pristine
查看是否有任何字段已更改,也可以使用表单上每个输入的属性上的
$pristine
属性查看该输入是否已更改。您甚至可以迭代
myForm
对象(非输入字段对象的键前缀为
$
):

angular.forEach($scope.myForm,函数(值,键){
如果(键[0]='$')返回;
console.log(键,值$pristine)
});
//首先,是真的
//最后,错

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

如果存储保存的值,并且还具有编辑的值,则可以在保存的值不变时重置回保存的值。然后,您可以比较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很简单,它假设两个对象具有相同的键,只有值发生了更改。我们复制这些对象,这样它们就不会成为对同一对象的两个引用,而实际上是两个对象。

旧线程但要基于SharpieOne的答案,您可能需要使用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;
}

以阿恩和夏皮奥的答案为基础。如果在项目中使用下划线,可以采用这种方法查找对象数组中的差异

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

仅在提交事件中使用更改的值检索对象的简单方法:

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

for (var i = 0; i < dirtyInput.length; i++) {
  change[dirtyInput[i].name] = dirtyInput[i].value;
}
var dirtyInput=$('#myForm.ng dirty');
var-change={};
对于(var i=0;i
向中添加更多内容。原始对象和编辑对象之间的差异也可能是由于在编辑对象中添加了新字段。因此,需要对同一问题进行额外检查

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

您可以使用
angular.copy(source,dest)
而不是编写自己的
clone
函数。不过我很喜欢你的方法,我忘了+祝你好运,先生。(编辑回答以反映这一点)假设用户进入页面,
firstName
字段为空<代码>$scope.firstName.$pristine
此时设置为
true
。然后用户输入“foo”<代码>$scope.firstName.$pristine现在设置为
false
。然后,用户后退三次,使输入保持为空,与原来一样<代码>$scope.firstName.$pristine继续设置为
false
@WalterRoman,这是正确的
$pristine
定义为:“如果用户尚未与表单交互,则为True”。我希望设置焦点或更新更新元素的背景色。如何使用“值”对象来实现这一点?或者我应该使用哪个对象和哪个属性?是否有任何选项用于标识在复选框中更改的范围值,并选择使用$pristine的下拉列表,而不是在迭代表单时获取范围字段