Javascript 什么';等待根据指令启动的承诺得到解决的最佳方式是什么?

Javascript 什么';等待根据指令启动的承诺得到解决的最佳方式是什么?,javascript,angularjs,angularjs-directive,angular-http,Javascript,Angularjs,Angularjs Directive,Angular Http,这是一个简单的表单,包含一个带有指令的输入字段。如果输入有效,该指令将调用远程服务器。响应将用一些额外的数据填充表单模型 提交表单时,我如何等待承诺解决 以下是一些示例代码,以防有所帮助: app.directive('getSecretStuff', function($q, $http) { function get_some_secret_stuff( value ) { var deferred = $q.defer(); $http.get

这是一个简单的表单,包含一个带有指令的输入字段。如果输入有效,该指令将调用远程服务器。响应将用一些额外的数据填充表单模型

提交表单时,我如何等待承诺解决

以下是一些示例代码,以防有所帮助:

app.directive('getSecretStuff', function($q, $http) {

    function get_some_secret_stuff( value ) {

        var deferred = $q.defer();

        $http.get(url)
        .success(function (response) {
            deferred.resolve(response.secret_stuff);
        });

        return deferred.promise;

    };

    return {
        restrict: 'A',
        require: '^form',
        scope: {
            secret_stuff: '=stuff',
        },
        link: function(scope, element, attrs, ctrl) {
            scope.$watch(
                function() { return ctrl[ element.attr('name') ].$valid; },
                function (validity) {
                    if (validity) {
                        get_some_secret_stuff( element.val() ).then(function( stuff ) {
                            scope.secret_stuff = stuff;
                        });
                    }
                }
            );

        },
    };
});
(Mis)使用异步验证器禁用表单提交,直到承诺得到解决 您可以(mis)使用异步验证程序来执行此操作。在异步验证器承诺中使用extra设置表单模型,然后使用表单的
$pending
禁用表单的提交按钮,直到承诺得到解决(如果需要)

HTML

<div ng-app="myApp">
    <div ng-controller="ctrlr">
        <form name="form" novalidate ng-submit="!form.$pending && submit()">
            <!-- our validaty check is just a sample - check for numbers -->
            <input ng-model="publicStuff" name="publicStuff" get-secret-stuff stuff="secretStuff" ng-pattern="/^[0-9]+$/" />
            <input ng-model="secretStuff" />
            <button type="submit">Go</button>
        </form>
    </div>
</div>

这是一个很好的解决办法。但是,我确实希望提交按钮在请求完成之前保持可单击状态。如果确实发生这种情况,应用程序应该等待指令请求结束(
!form.$pending
,在代码中),然后启动
POST
请求(我将使用一个无限循环,其中包含一个
$timeout
。但是,我的问题实际上更多的是关于通知控制器请求完成的通道和
表单。$pending
看起来足够合适。请用我上面的建议更新您的答案,以便我接受它!删除提交按钮上禁用的ng!
angular.module('myApp', [])
    .controller('ctrlr', function ($scope) {
    })
    .directive('getSecretStuff', function ($q, $timeout) {
        function get_some_secret_stuff(value) {
            var deferred = $q.defer();
            // for illustration, we use the $timeout instead of $http 
            // swap this out with the actual $http call in your code
            $timeout(function () {
                deferred.resolve('secret value for ' + value);
            }, 2000)
            return deferred.promise;
        };

        // a promise that resolves immediately
        function get_dummy_promise() {
            var deferred = $q.defer();
            console.log('asd')
            deferred.resolve('1');
            return deferred.promise;
        };

        return {
            restrict: 'A',
            require: ['^form', 'ngModel'],
            scope: {
                secret_stuff: '=stuff',
            },
            link: function (scope, element, attrs, ctrlrs) {
                // we misuse the async validator to... 
                ctrlrs[1].$asyncValidators.secretStuff = function (modelValue, viewValue) {
                    if (viewValue)
                        return get_some_secret_stuff(viewValue).then(function (response) {
                            // ...do work other than validation
                            scope.secret_stuff = response;
                            return true;
                        });
                    else
                        // this is just for the first run when the validator gets called even if $valid is not set
                        return get_dummy_promise().then(function (response) {
                            scope.secret_stuff = undefined;
                            return true;
                        });
                };

                // we probably want to clear out the secret stuff for invalid values
                scope.$watch(
                    function () { return ctrlrs[0][element.attr('name')].$valid; },
                    function (validity) {
                        if (!validity) {
                            scope.secret_stuff = undefined;
                        }
                    }
                );
            },
        };
    });