Примечания: Я использую AngularJS 1,2Angularjs только последний вызов асинхронного в директиве фактически выполняется
У меня есть форма, где каждое поле ударит сервер для проверки на значении изменились.
HTML-фрагмент ниже (Предположим, что для всех целей HTML настроен правильно):
<div class="col-sm-5">
<input class="form-control input-sm" url="type:googleplus" ng-model="element.googleplus" type="text"><br />
<input class="form-control input-sm" url="type:yelp" ng-model="element.yelp" type="text"><br />
<input class="form-control input-sm" url="type:foursquare" ng-model="element.foursquare" type="text>
</div>
В моей JavaScript я создал директиву, которая перехватывает в каждый и пытается попасть на сервер при обновлении значения. Сценарий, который нарушает текущую функциональность, - это когда форма загружается с заполненными значениями.
OnValueChanged вызывает Validate.Options несколько раз без паузы между ними. Я ожидал, что сервер будет удален для каждого запроса Validation.Options, но вместо этого выполняется только последний вызов.
AngularJS ниже:
...
.factory('Validation', ['va', function (va) { // 'va' is a throttled resource
var result = va('/manage/api/validate?type=:type&input=:url',
{
type: '@type',
url: '@url'
},
{
options: {
method: 'options',
debounceMS: 0, // turned off debounce in lieu of this problem
abortPending: false
}
});
return result;
}])
...
.directive('url', ['$filter', 'Validation', '$q', function ($filter, Validation, $q) {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
// parses some stuff
var config = {};
(attrs['url'] || '').split(' ').map(function (p) { var a = p.split(':'); config[a[0]] = a[1]; });
if (config.type)
config.type = config.type.split(',');
config.isRequired = elm[0].required;
function validateUrl(viewValue, type) {
var deferred = $q.defer();
Validation.options({ url: viewValue, type: type }, function (response) {
deferred.resolve(response.IsValid);
});
return deferred.promise;
}
function onValueChanged(viewValue) {
// hits the server to check if the url is valid
if (viewValue) {
var type = config.type ? config.type[0] : undefined;
validateUrl(viewValue, type).then(function (isValid) {
ctrl.$setValidity('url', isValid);
});
}
else {
// prevents saving the listing as field is invalid
ctrl.$setValidity('url', !config.isRequired);
}
return viewValue;
}
ctrl.$parsers.push(onValueChanged);
// revalidate when the model updates
scope.$watch(
function() { return ctrl.$viewValue; },
function (viewValue) { return onValueChanged(viewValue); }
);
}
};
}])
Почему только последний вызов будет выполнен? Открыв вкладку сети, я вижу ровно один серверный вызов с типом «foursquare».