APIにデータをPUTする編集フォーム(user.html)で作業していますが、フォーム内のすべてのデータをPUTしないようにしたいと思います。変更したアイテムだけをPUTしたいです。
フォームを操作するときにダーティで自然のままの使用を見てきましたが、これはフォームのすべての変更に適用されます。 ng-changeの使用も確認しましたが、1つの要素への変更に対してアクションをトリガーしたくありません。変更された要素がPUTに含まれていることを示すだけです。
誰もが変更された入力フィールドのみを示す方法を見つけましたか?
入力をform
属性を持つname
に入れてから、入力に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
を使用して、anyフィールドが変更されたかどうかを確認し、フォーム上の各入力のプロパティの$pristine
プロパティでその入力が変更されました。 myForm
オブジェクトを繰り返し処理することもできます(非入力フィールドオブジェクトには、$
というプレフィックスが付いたキーがあります)。
angular.forEach($scope.myForm, function(value, key) {
if(key[0] == '$') return;
console.log(key, value.$pristine)
});
// first, true
// last, false
ユーザーに設定/情報の更新を許可する場合、より多くの機能が必要になることがよくあります。情報をリセットしたり、編集をキャンセルして元に戻す機能など。これはリクエストの一部ではなかったと思いますが、これを考慮すると、他のことが簡単になります。
保存された値を保存し、編集された値も持っています。変更されていないため、保存された値にリセットできます。次に、2を比較して、何が変わったかを判断できます。
動作例: http://jsfiddle.net/TheSharpieOne/nJqTX/2/
コンソールログを見て、この例のフォームを送信すると何が変更されたかを確認してください。これは、PUTを介して簡単に送信できるオブジェクトです。
function myCtrl($scope) {
$scope.user = {
firstName: "John",
lastName: "Smith",
email: "[email protected]"
};
$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つの参照ではなく、実際には2つのオブジェクトになるようにします。
古いスレッドですが、TheSharpieOneの答えに基づいて構築するには、「===」の代わりにangle.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;
}
$scope.$watch('scopeVariable', function(oldValue, newValue)...)
を使用して、newValue
sとは異なるoldValue
sのみを含むオブジェクトを作成できます。
link to Angular $ watchに関するドキュメント。
ARNとTheSharpieOneの答えを構築します。プロジェクトでアンダースコアを使用している場合は、この方法を使用してオブジェクトの配列の違いを見つけることができます。
function findDiff(original, edited){
_.filter(original, function(obj){ return !_.findWhere(edited, obj); });
}
Submitイベントで値が変更されたオブジェクトのみを取得する簡単な方法:
var dirtyInput = $('#myForm .ng-dirty');
var change = {};
for (var i = 0; i < dirtyInput.length; i++) {
change[dirtyInput[i].name] = dirtyInput[i].value;
}
TheSharpieOne's answer にさらに追加します。元のオブジェクトと編集済みの差分は、編集済みオブジェクトに追加された新しいフィールドが原因である可能性もあります。したがって、同じための追加のチェック
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;
}