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