Javascript 避免设置超时以重叠angular$watch上的功能

Javascript 避免设置超时以重叠angular$watch上的功能,javascript,angularjs,Javascript,Angularjs,我有这个验证过程,根据第一个函数的返回,两个div淡入淡出。setTimeout是让finish键入输入,因为它在keyup上监视。系统工作正常,但在以下情况下会出现问题: 键入错误值(#显示错误)>重新键入正确值>键入正确值时,会触发else函数,因为它尚未完成>键入正确值时(.ok显示)设置超时延迟后,#错误也会显示 有没有办法避免else函数的重叠?也许完全分离真函数和假函数 function validatePasscode(code) { if (array.indexOf(c

我有这个验证过程,根据第一个函数的返回,两个div淡入淡出。setTimeout是让finish键入输入,因为它在keyup上监视。系统工作正常,但在以下情况下会出现问题:

键入错误值(#显示错误)>重新键入正确值>键入正确值时,会触发else函数,因为它尚未完成>键入正确值时(.ok显示)设置超时延迟后,#错误也会显示

有没有办法避免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);
    }
});

请始终调用clearTimeout()


}))

我会采取一些不同的方法。Angular的思想不是在控制器内部进行DOM操作。您有几个选项—一个选项是在$scope上公开$isValid,另一个选项是创建执行动画的指令

至于限制输入,问题是你在每次按键后任意等待2秒钟。您真正想要的是等待按键设置,即只要有人键入wait,然后在暂停一段时间后重新评估

您可以使用下划线或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
   }
}

下面是我的一把工作小提琴,它使用了一个类似的概念:(我正在过滤而不是验证,但你可以看到油门是如何工作的)和一篇关于它的博客文章:

谢谢,逻辑似乎很好,但问题仍然存在。我应该使用$timeout而不是setTimeout吗?在Angular中,您肯定应该使用$timeout而不是setTimeout谢谢,它可以工作。现在唯一的问题是将开头的空输入字段视为failure(从而显示failure div)。是否可以仅在开始键入后应用验证功能?现在我将使用它,我正在学习,我将看看expose$的有效性。不用担心,您可以只做两件事中的一件。如果要忽略空,只需使用u.isEmpty()检查并仅验证它是否为空(即,他们开始键入)。如果您想在初始值之后检查是否为空,那么您可以在第一次不为空时设置一个标志,并以这种方式进行检查。如果您在表单中绑定HTML,则有更多选项,例如$pristine和$dirty。
var applyValidation = function($scope) {
   if(validatePasscode($scope.passcode)) {
      // success animation
   } 
   else {
      // failure animation
   }
}