har*_*shr 12 angularjs angularjs-directive
在DRY主体之后,我想写一个按钮指令,它在$ http类的持续时间内保持按钮被禁用.
我想这样做是为了禁止用户多次单击按钮,但我无法考虑如何在指令中获取函数承诺状态,因为函数驻留在$ scope
该场景非常通用,按钮ng-click确实调用了一个函数,该函数又进行$ http调用.用户点击:按钮应该被禁用,只有在$ http调用解决后才能启用,无论是成功还是失败.
Art*_*ich 37
为什么不让它变得更容易.
<button ng-click="save()" ng-disabled="isProcessing">Save</button>
$scope.save = function(){
$scope.isProcessing = true;
$http.post('Api/Controller/Save', data).success(
$scope.isProcessing = false;
);
}
Run Code Online (Sandbox Code Playgroud)
当然,如果您在应用程序中的极少数地方需要此逻辑,则会出现这种情况.
如果你有这样的逻辑重复多次(如果你不是懒惰:)),那么为了遵循SOLID原则,它最好将这个功能包装成指令(查看这个问题的其他答案以查看这样的指令的例子) .
Mic*_*mza 29
虽然我会小心过度工程,但实现这一点的方法是使用自定义指令.这个指令
finally承诺上,它重新启用按钮-
app.directive('clickAndDisable', function() {
return {
scope: {
clickAndDisable: '&'
},
link: function(scope, iElement, iAttrs) {
iElement.bind('click', function() {
iElement.prop('disabled',true);
scope.clickAndDisable().finally(function() {
iElement.prop('disabled',false);
})
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
这可以在按钮上使用,如下所示:
<button click-and-disable="functionThatReturnsPromise()">Click me</button>
Run Code Online (Sandbox Code Playgroud)
您可以在http://plnkr.co/edit/YsDVTlQ8TUxbKAEYNw7L?p=preview中看到此操作,其中返回promise的函数是:
$scope.functionThatReturnsPromise = function() {
return $timeout(angular.noop, 1000);
}
Run Code Online (Sandbox Code Playgroud)
但是你可以替换$timeout与一个呼叫$http,或从返回一个承诺任何服务的功能.
我喜欢@ codef0rmer的解决方案,因为它是集中式的 - 即每个HTTP请求都不需要额外的代码,您只需要检查progressHTML中的全局标志.但是,transformResponse用于确定请求何时完成是不可靠的,因为服务器可能不会返回任何内容; 在这种情况下,处理程序不会被调用,progress并且永远不会被设置回false.此外,如所写,答案不考虑多个同时请求(progress可能false在所有请求完成之前返回).
我提出了一个类似的解决方案,它使用拦截器来解决这些问题.你可以把它放在你的Angular应用程序的配置功能中:
.config(function ($httpProvider) {
$httpProvider.interceptors.push(function($q, $rootScope) {
var numberOfHttpRequests = 0;
return {
request: function (config) {
numberOfHttpRequests += 1;
$rootScope.waitingForHttp = true;
return config;
},
requestError: function (error) {
numberOfHttpRequests -= 1;
$rootScope.waitingForHttp = (numberOfHttpRequests !== 0);
return $q.reject(error);
},
response: function (response) {
numberOfHttpRequests -= 1;
$rootScope.waitingForHttp = (numberOfHttpRequests !== 0);
return response;
},
responseError: function (error) {
numberOfHttpRequests -= 1;
$rootScope.waitingForHttp = (numberOfHttpRequests !== 0);
return $q.reject(error);
}
};
});
})
Run Code Online (Sandbox Code Playgroud)
现在您可以使用waitingForHttp禁用按钮(或显示"忙"页面).使用拦截器可以获得额外的好处,现在您可以使用错误函数将所有HTTP错误记录在一个地方(如果需要).
您可以在运行块中使用它.这将确保在有活动的XHR呼叫时将禁用所有按钮.
myApp.run(function($rootScope, $http) {
$http.defaults.transformRequest.push(function (data) {
$rootScope.progress = true;
return data;
});
$http.defaults.transformResponse.push(function(data){
$rootScope.progress = false;
return data;
})
});
Run Code Online (Sandbox Code Playgroud)
然后在任何地方使用相同的型号.
<button ng-click="save()" ng-disabled="progress">Save</button>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23434 次 |
| 最近记录: |