我正在編寫一個將數據發送到API的編輯表單(user.html),但我想避免在表單中填寫所有數據。我想把PUT只是改變的項目。我如何表示在AngularJS中哪些輸入字段發生了變化
我在使用窗體時看到了使用髒和純淨的東西,但這適用於窗體中的任何更改。我也看到了ng-change的用法,但我不想觸發對一個元素進行更改的操作,只是表示更改後的元素應該包含在PUT中。
任何人都找到一種方法來表示只有輸入字段已更改?
我正在編寫一個將數據發送到API的編輯表單(user.html),但我想避免在表單中填寫所有數據。我想把PUT只是改變的項目。我如何表示在AngularJS中哪些輸入字段發生了變化
我在使用窗體時看到了使用髒和純淨的東西,但這適用於窗體中的任何更改。我也看到了ng-change的用法,但我不想觸發對一個元素進行更改的操作,只是表示更改後的元素應該包含在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
看是否任何領域已經改變,看到$pristine
屬性窗體上的每個輸入的財產,如果該輸入已經改變。你甚至可以遍歷myForm
對象(非輸入字段對象有一個$
前綴鍵):
angular.forEach($scope.myForm, function(value, key) {
if(key[0] == '$') return;
console.log(key, value.$pristine)
});
// first, true
// last, false
您可以使用$scope.$watch('scopeVariable', function(oldValue, newValue)...)
並構建一個只包含newValue
的對象,該對象與oldValue
不同。
以下是有關$ watch的Angular文檔的link。
我經常發現,允許用戶更新設置/信息時,你會想更多的功能。如重置信息或取消編輯並恢復的能力。我知道這不是要求的一部分,但是當你考慮這一點時,這會讓其他事情變得更容易。
您可以存儲已保存的值並且也具有已編輯的值,您可以重置爲保存的值,因爲它們不會更改。然後你可以比較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個對象。
您可以使用'angular.copy(source,dest)'而不是自己寫克隆功能。儘管我喜歡你的方法。 –
我忘了那個。給你+1好先生。 (編輯回答這個反射) – TheSharpieOne
舊的線程,但要建立在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;
}
建立關閉ARN和TheSharpieOne的答案。如果您在項目中使用下劃線,則可以採用此方法來查找對象數組中的差異。
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;
}
到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;
}
假設用戶進入該頁面,並且'firstName'字段爲空。 '$ scope.firstName。$ pristine'在這一點上被設置爲'true'。用戶然後輸入「foo」。 '$ scope.firstName。$ pristine'現在被設置爲'false'。用戶然後退回三次,以保持輸入爲空,就像原來的那樣。 '$ scope.firstName。$ pristine'繼續被設置爲'false'。 –
@WalterRoman這是正確的。 '$ pristine'在[docs](https://docs.angularjs.org/api/ng/type/form.FormController)中定義爲:「如果用戶尚未與表單交互,則返回true」 –
我希望設置焦點或更新更新元素的背景顏色。我如何使用'value'對象來做到這一點?或者我應該使用哪個對象以及哪個屬性? –