#angularjs
#angularjs
Вопрос:
У меня есть проблема, которую я смог решить, используя тайм-аут. Это похоже на очень плохую практику, которая может привести к недостижимому беспорядку, и я ищу лучший способ решить эту проблему.
Есть идеи?
Надеюсь, понятный JSFiddle проблемы
<div ng-app="test" ng-controller="Ctrl">
<form name="form">
<input custom-validation type="text" ng-model="model" name="text" />
it should not allowed to send the word 'fail'
</form>
<button ng-click="fillAndSend()">Fill with 'fail' and send</button>
<button ng-click="send()">Send</button>
<h1>Success: {{success}}</h1>
angular.module('test', []);
angular.module('test').directive('customValidation', function () {
'use strict';
return {
require: '?ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
scope.$watch(attrs.ngModel, function (value) {
if (value == 'fail') {
ngModelCtrl.$setValidity('customValidation', false);
} else {
ngModelCtrl.$setValidity('customValidation', true);
}
});
}
};
});
angular.module('test').controller('Ctrl', function ($scope, $timeout) {
$scope.success = false;
$scope.model;
$scope.fillAndSend = function() {
$scope.model = 'fail';
$scope.send();
/* using a timeout works
$timeout(function(){
$scope.send();
},0);
*/
}
$scope.send = function () {
if ($scope.form.$valid) {
$scope.success = true;
} else {
$scope.success = false;
}
}
});
Ответ №1:
Я полагаю, это связано с тем, что цикл angular $ digest выполняется здесь только один раз. Использование $timeout заставляет вторую часть того, что вы делаете, выполнять второй цикл дайджеста, поэтому он работает с $timeout . Вы не можете просто вызвать $scope.$apply()
, потому что вы уже находитесь в цикле дайджеста. В этом случае использование тайм-аута является правильным решением, потому что вам нужно, чтобы angular понял, что модель изменилась, а ЗАТЕМ вызвал функцию отправки.
Другой вариант — установить флаг в контроллере, который необходимо вызывать для отправки, поскольку вы меняете модель. А затем в вашей директиве, где вы просматриваете модель, вы можете проверить, нужно ли вызывать send
Комментарии:
1. Некоторые асинхронные службы и поставщики используют встроенный
$timeout
для запуска цикла $digest . Это аккуратный трюк, и в нем нет ничего плохого.
Ответ №2:
scope.$apply() может помочь :
$scope.fillAndSend = function() {
$scope.model = 'fail';
$scope.$apply();
$scope.send();
/* using a timeout works
$timeout(function(){
$scope.send();
},0);
*/
}