我有这个验证过程,根据第一个函数的返回,淡入或淡出两个div。 setTimeout是为了完成输入,因为它在keyup上监视。系统有效,但问题发生在:
您键入了错误的值(#wrong显示)>你重新输入好的价值>当你输入好的值时,会触发else函数,因为它尚未完成>键入好的值时(.ok显示) #wong显示为并且在setTimeout延迟之后。
有没有办法避免else函数的重叠?也许完全分离真假函数?
function validatePasscode(code) {
if (array.indexOf(code) > -1) {
return true;
}
}
$scope.$watch('passcode', function(value) {
var isValid = validatePasscode(value);
if (isValid) {
$scope.loadNewChannel();
$('.ok').fadeIn(200);
$('#wrong').fadeOut(200);
}
else {
setTimeout(function(){
$('.ok').fadeOut(200);
$('#wrong').delay(200).fadeIn(200);
},2000);
}
});
答案 0 :(得分:1)
我会采取一些不同的方法。 Angular的想法不是在控制器内部进行DOM操作。您有几个选项 - 一个是在$ scope上公开$ isValid,另一个是创建一个执行动画的指令。
至于限制输入,问题是你在每次按键后任意等待2秒。你真正想要的是等到按键结束 - 即只要有人打字等待,然后一旦他们暂停一段时间重新评估。
你可以使用Underscore或Lo-dash的去抖动来做到这一点。像这样:
var applyValidation = function($scope) {
$scope.isValid = validatePasscode($scope.passcode);
}
因为debounce在Angular的摘要循环之外触发,你需要$应用它:
var validationDelayed = function($scope) {
$scope.$apply(function(){applyValidation($scope);});
};
然后你可以观看它,只有在输入结束后才会做出反应。这只会在用户停止输入1秒后触发检查:
var validationThrottled = _.debounce(validationDelayed, 1000);
$scope.$watch('passcode', function(){validationThrottled($scope);});
同样,这将解决超时问题,但我强烈建议将其转换为动画的指令,尽管您可以在此代码中尝试这样:
var applyValidation = function($scope) {
if(validatePasscode($scope.passcode)) {
// success animation
}
else {
// failure animation
}
}
这是我的一个工作小提琴,它使用了一个类似的概念:http://jsfiddle.net/jeremylikness/5KeMw/(我正在过滤而不是验证,但你可以看到油门是如何工作的)以及一篇关于它的博客文章:http://csharperimage.jeremylikness.com/2013/10/throttling-input-in-angularjs.html
答案 1 :(得分:0)
请始终调用clearTimeout()
var timeoutFunction;
$scope.$watch('passcode', function(value) {
var isValid = validatePasscode(value);
clearTimeout(timeoutFunction);
if (isValid) {
$scope.loadNewChannel();
$('.ok').fadeIn(200);
$('#wrong').fadeOut(200);
}
else {
setTimeout(function(){
$('.ok').fadeOut(200);
$('#wrong').delay(200).fadeIn(200);
},2000);
}
});