避免Angular应用程序中的超时

时间:2014-06-25 14:34:55

标签: angularjs

我有一个问题,我能够使用超时解决。这感觉就像一个非常糟糕的做法,可能导致无法维护的混乱,我正在寻找一种更好的方法来解决这个问题。

有什么想法吗?

A hopefully self-explanatory JSFiddle of the problem

<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;
        }
    }
});

2 个答案:

答案 0 :(得分:3)

我相信这是因为角度$摘要周期只发生在这里一次。使用$ timeout,将你所做的第二部分强制转换为第二个摘要周期,这就是为什么它与$ timeout一起使用。您不能只是致电$scope.$apply(),因为您已经处于摘要周期。在这种情况下,使用超时是正确的事情,因为你需要角度来实现模型的改变,然后调用发送函数。

另一个选项是在控制器中设置一个标志,因为您要更改模型,所以需要调用send。然后在您观察模型的指令中,您可以检查是否需要调用发送

答案 1 :(得分:-1)

范围。$ apply()可能有所帮助:

 $scope.fillAndSend = function() {
    $scope.model = 'fail';
    $scope.$apply();
    $scope.send();
    /* using a timeout works
    $timeout(function(){
        $scope.send();    
    },0);
    */
}