AngularJS - Размытие + Изменено?
Каков самый простой способ комбинировать ng-changed и ng-blur?
Я нашел этот пост: Как разрешить ng-model не обновляться сразу?
Однако это больше не работает в angluar 1.2+
Есть ли способ достичь такого же поведения?
Думаю, мне нужно сохранить копию старого значения самостоятельно и сравнить новое значение с тем, что при размытии, если я попытаюсь сделать то же самое, или есть ли более простой способ?
Ответы
Ответ 1
Это делает то, что я хочу.
Он сохраняет значение в фокусе и сравнивает его с новым значением при размытии, если оно изменено, оно вызывает выражение в атрибуте.
app.directive('changeOnBlur', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ngModelCtrl) {
if (attrs.type === 'radio' || attrs.type === 'checkbox')
return;
var expressionToCall = attrs.changeOnBlur;
var oldValue = null;
elm.bind('focus',function() {
scope.$apply(function() {
oldValue = elm.val();
console.log(oldValue);
});
})
elm.bind('blur', function() {
scope.$apply(function() {
var newValue = elm.val();
console.log(newValue);
if (newValue !== oldValue){
scope.$eval(expressionToCall);
}
//alert('changed ' + oldValue);
});
});
}
};
});
использование:
<input ng-model="foo" change-on-blur="someFunc()" />
Ответ 2
Используйте ng-model options
.
Таким образом, ng-change
будет запускаться только при размытии ввода.
<input type="text"
ng-model="a.b"
ng-model-options="{updateOn: 'blur'}"
ng-change="onchange()"/>
Ответ 3
Как насчет этого решения. Работает для меня:
<input ng-init="oldValue = value" ng-model="value"
ng-blur="oldValue != value && callYourFunc(foo)">
Ответ 4
как насчет this plunkr?
используя angular встроенный ng-blur
, обновите свое "сохраненное значение" при размытии
<input type="text" ng-model="boxValue" ng-blur="doneEditing(boxValue)">
при сохранении, проверьте, что значение отличается
$scope.doneEditing = function(v) {
if (v !== $scope.persistedValue) // only save when value is different
$scope.persistedValue=v;
}
В ng-blur
нет специальной опции для предварительного проверки равенства, о котором я знаю. Простой if
, кажется, делает трюк
Ответ 5
Я использую AngularJs 1.2.x и наткнулся на проблему ng-change обстрела при каждом изменении. ng-blur можно использовать, но он срабатывает, даже если нет никакого изменения в значении. Поэтому оба нельзя эффективно использовать.
С Angularjs 1.3.x все проще, используя ng-model-options
, как показано ниже
, чтобы вызвать функцию изменения "onBlur"
ng-change="ctrl.onchange()" ng-model-options="{updateOn: 'blur'}"
И
, чтобы отложить вызов функции изменения на 500 мс
ng-change="ctrl.onchange()" ng-model-options='{ debounce: 500 }'"
Теперь, чтобы вернуться к вопросу о получении таких вещей с помощью AngularJs 1.2.x
, чтобы вызвать функцию изменения "onBlur"
HTML
<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange()" />
или
<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange(ctrl.a.c)" />
JS
app.directive('sdChangeOnBlur', function() {
return {
restrict: 'A',
scope: {
sdChangeOnBlur: '&'
},
link: function(scope, elm, attrs) {
if (attrs.type === 'radio' || attrs.type === 'checkbox')
return;
var parameters = getParameters(attrs.sdChangeOnBlur);
var oldValue = null;
elm.bind('focus', function() {
scope.$apply(function() {
oldValue = elm.val();
});
})
elm.bind('blur', function() {
scope.$apply(function() {
if (elm.val() != oldValue) {
var params = {};
if (parameters && parameters.length > 0) {
for (var n = 0; n < parameters.length; n++) {
params[parameters[n]] = scope.$parent.$eval(parameters[n]);
}
} else {
params = null;
}
if (params == null) {
scope.sdChangeOnBlur();
} else {
scope.sdChangeOnBlur(params)
}
}
});
});
}
};
});
function getParameters(functionStr) {
var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
var params;
if (paramStr) {
params = paramStr.split(",");
}
var paramsT = [];
for (var n = 0; params && n < params.length; n++) {
paramsT.push(params[n].trim());
}
return paramsT;
}
, чтобы отложить вызов функции изменения на 500 мс
HTML
<input type="text" ng-model="name" sd-change="onChange(name)" sd-change-delay="300"/>
ИЛИ
<input type="text" ng-model="name" sd-change="onChange()" sd-change-delay="300"/>
JS
app.directive('sdChange', ['$timeout',
function($timeout) {
return {
restrict: 'A',
scope: {
sdChange: '&',
sdChangeDelay: '@' //optional
},
link: function(scope, elm, attr) {
if (attr.type === 'radio' || attr.type === 'checkbox') {
return;
}
if (!scope.sdChangeDelay) {
scope.sdChangeDelay = 500; //defauld delay
}
var parameters = getParameters(attr.sdChange);
var delayTimer;
elm.bind('keydown keypress', function() {
if (delayTimer !== null) {
$timeout.cancel(delayTimer);
}
delayTimer = $timeout(function() {
var params = {};
if (parameters && parameters.length > 0) {
for (var n = 0; n < parameters.length; n++) {
params[parameters[n]] = scope.$parent.$eval(parameters[n]);
}
} else {
params = null;
}
if (params == null) {
scope.sdChange();
} else {
scope.sdChange(params)
}
delayTimer = null;
}, scope.sdChangeDelay);
scope.$on(
"$destroy",
function(event) {
$timeout.cancel(delayTimer);
console.log("Destroyed");
}
);
});
}
};
}
]);
function getParameters(functionStr) {
var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
var params;
if (paramStr) {
params = paramStr.split(",");
}
var paramsT = [];
for (var n = 0; params && n < params.length; n++) {
paramsT.push(params[n].trim());
}
return paramsT;
}
plnkrs для обоих подходов
http://plnkr.co/edit/r5t0KwMtNeOhgnaidKhS?p=preview
http://plnkr.co/edit/9PGbYGCDCtB52G8bJkjx?p=info
Ответ 6
Новые версии AngularJS (теперь в версии 1.3 beta) поддерживают это изначально. См. мой ответ здесь
Ответ 7
Решение, которое сработало для меня, было следующим:
<input id="fieldId" type="text"
ng-model="form.fields.thisField"
ng-model-options="{ updateOn: 'blur' }"
ng-change="form.save()" />
Я нашел это решение здесь
Эта страница говорит, что для нее требуется версия AngularJS 1.3.0+. Я протестировал его с версией AngularJS 1.5.11, и он работает в этой версии для меня.
Ответ 8
В app.html
<input type="text" name="name" ng-model="$ctrl.user.name" ng-blur="$ctrl.saveChanges()" ng-change="$ctrl.onFieldChange()"/>
в приложениях
public onFieldChange() {
this.isValuesModified = true;
}
//save changes on blur event
public saveChanges() {
//check if value is modified
if(this.isValuesModified){
//Do your stuff here
}
}