Как я могу указать, какие поля ввода изменились в AngularJS
Я работаю над формой редактирования (user.html), которая передает данные PUT в API, но я бы хотел, чтобы не удалять все данные в форме. Я хотел бы НАПРАВИТЬ только измененные элементы.
Я видел использование грязных и нетронутых при работе с формами, но это относится к любому изменению формы. Я также видел использование ng-change, но я не хочу запускать действие при изменении одного элемента, просто означаю, что измененный элемент должен быть включен в PUT.
Кто-нибудь нашел способ обозначить только измененные поля ввода?
Ответы
Ответ 1
Если вы поместите ввод в 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
(объекты без полей ввода имеют ключи с префиксом $
):
angular.forEach($scope.myForm, function(value, key) {
if(key[0] == '$') return;
console.log(key, value.$pristine)
});
// first, true
// last, false
Ответ 2
Я часто обнаруживаю, что вам нужно больше функциональности, позволяя пользователям обновлять настройки/информацию. Например, возможность reset получить информацию или отменить редактирование и вернуться назад. Я знаю, что это не было частью запроса, но когда вы это считаете, это облегчает другие вещи.
Сохраняемые сохраненные значения, а также отредактированные значения, вы можете reset вернуться к сохраненным значениям, так как они не изменяются. Затем вы можете сравнить 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 объекта.
Ответ 3
старый поток, но для построения ответа 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;
}
Ответ 4
Вы можете использовать $scope.$watch('scopeVariable', function(oldValue, newValue)...)
и построить объект, содержащий только newValue
, которые отличаются от oldValue
s.
Здесь ссылка на Angular документы относительно $watch.
Ответ 5
Создание ответов ARN и TheSharpieOne. Если вы используете подчеркивание в своем проекте, вы можете использовать этот подход для поиска различий в массивах объектов.
function findDiff(original, edited){
_.filter(original, function(obj){ return !_.findWhere(edited, obj); });
}
Ответ 6
Простой способ получить объект только с измененными значениями на событие отправки:
var dirtyInput = $('#myForm .ng-dirty');
var change = {};
for (var i = 0; i < dirtyInput.length; i++) {
change[dirtyInput[i].name] = dirtyInput[i].value;
}