Angular 指令:按钮微调器
Angular Directive: Button Spinner
我创建了一个指令,它的行为就像当你点击按钮时它会显示微调器或加载器,它向用户显示正在进行的事情,比如 API 调用或移动到另一个页面,我正面临以下问题:
如果页面上使用了多个指令,它会为两个按钮显示微调器而不是单击按钮,我希望它只为单击按钮显示
在某些情况下,单击事件绑定了三次,因为按钮内部使用了三个 span 来显示微调器,事件传播存在一些问题
指令代码如下:
(function () {
'use strict';
angular
.module('app.base')
.directive('buttonSpinner', directiveFunction)
.controller('btnController', ControllerFunction);
// ----- directiveFunction -----
directiveFunction.$inject = [];
/* @ngInject */
function directiveFunction() {
var directive = {
restrict: 'E',
scope: {
label: "@",
available: "="
},
controller: 'btnController',
controllerAs: 'vm',
replace: true,
transclude: true,
template:
'<button ng-disabled="vm.isDisabled">'
+ '<span ng-hide="vm.isClicked">{{label}}</span>'
+ '<div class="spinner" ng-show="vm.isClicked">'
+ '<span class="bounce1"></span>'
+ '<span class="bounce2"></span>'
+ '<span class="bounce3"></span>'
+ '</div>' +
'</button>'
};
return directive;
}
// ----- ControllerFunction -----
ControllerFunction.$inject = [ '$scope' ];
/* @ngInject */
function ControllerFunction( $scope ) {
var vm = this;
vm.isClicked = false;
$scope.$on('APICALLED', function(event, data){
vm.isClicked = data.done;
if( data.elem ) {
angular.element(document.getElementById(data.elem))[0].disabled = true;
} else {
vm.isDisabled = data.disable;
}
});
}
})();
使用方法:
在视图中:
<button-spinner class="btn btn-primary btn-block btn-lg" type="submit" ng-click="vm.notifyMe($event)" label="Notify Me" available="vm.notify.is" id="notifyMeBtn"></button-spinner>
在控制器中:
显示微调器:
$rootScope.$broadcast('APICALLED', {'done': true, 'disable': true});
隐藏微调器:
$rootScope.$broadcast('APICALLED', {'done': false, 'disable': false});
您的问题与您的 $broadcast's
有关,因此它是模式问题。 $rootScope.$broadcast()
根本不是一个好的解决方案。例如)您需要手动销毁 $rootScope.$broadcast.$on()
绑定。只需将一个唯一的范围变量解析到指令中,如 loading
。对于每个加载过程,此范围参数可以由控制器本身处理:
/* @ngInject */
function directiveFunction() {
var directive = {
restrict: 'E',
scope: {
label: "@",
available: "=",
loading: "="
},
controller: 'btnController',
controllerAs: 'vm',
replace: true,
transclude: true,
template:
'<button ng-disabled="vm.isDisabled">'
+ '<span ng-hide="vm.isClicked">{{label}}</span>'
+ '<div class="spinner" ng-show="vm.loading">'
+ '<span class="bounce1"></span>'
+ '<span class="bounce2"></span>'
+ '<span class="bounce3"></span>'
+ '</div>' +
'</button>'
};
return directive;
}
查看
<button-spinner class="btn btn-primary btn-block btn-lg"
type="submit"
ng-click="vm.notifyMe($event)"
loading="vm.isLoading"
label="Notify Me"
available="vm.notify.is"
id="notifyMeBtn"></button-spinner>
我创建了一个指令,它的行为就像当你点击按钮时它会显示微调器或加载器,它向用户显示正在进行的事情,比如 API 调用或移动到另一个页面,我正面临以下问题:
如果页面上使用了多个指令,它会为两个按钮显示微调器而不是单击按钮,我希望它只为单击按钮显示
在某些情况下,单击事件绑定了三次,因为按钮内部使用了三个 span 来显示微调器,事件传播存在一些问题
指令代码如下:
(function () {
'use strict';
angular
.module('app.base')
.directive('buttonSpinner', directiveFunction)
.controller('btnController', ControllerFunction);
// ----- directiveFunction -----
directiveFunction.$inject = [];
/* @ngInject */
function directiveFunction() {
var directive = {
restrict: 'E',
scope: {
label: "@",
available: "="
},
controller: 'btnController',
controllerAs: 'vm',
replace: true,
transclude: true,
template:
'<button ng-disabled="vm.isDisabled">'
+ '<span ng-hide="vm.isClicked">{{label}}</span>'
+ '<div class="spinner" ng-show="vm.isClicked">'
+ '<span class="bounce1"></span>'
+ '<span class="bounce2"></span>'
+ '<span class="bounce3"></span>'
+ '</div>' +
'</button>'
};
return directive;
}
// ----- ControllerFunction -----
ControllerFunction.$inject = [ '$scope' ];
/* @ngInject */
function ControllerFunction( $scope ) {
var vm = this;
vm.isClicked = false;
$scope.$on('APICALLED', function(event, data){
vm.isClicked = data.done;
if( data.elem ) {
angular.element(document.getElementById(data.elem))[0].disabled = true;
} else {
vm.isDisabled = data.disable;
}
});
}
})();
使用方法:
在视图中:
<button-spinner class="btn btn-primary btn-block btn-lg" type="submit" ng-click="vm.notifyMe($event)" label="Notify Me" available="vm.notify.is" id="notifyMeBtn"></button-spinner>
在控制器中:
显示微调器:
$rootScope.$broadcast('APICALLED', {'done': true, 'disable': true});
隐藏微调器:
$rootScope.$broadcast('APICALLED', {'done': false, 'disable': false});
您的问题与您的 $broadcast's
有关,因此它是模式问题。 $rootScope.$broadcast()
根本不是一个好的解决方案。例如)您需要手动销毁 $rootScope.$broadcast.$on()
绑定。只需将一个唯一的范围变量解析到指令中,如 loading
。对于每个加载过程,此范围参数可以由控制器本身处理:
/* @ngInject */
function directiveFunction() {
var directive = {
restrict: 'E',
scope: {
label: "@",
available: "=",
loading: "="
},
controller: 'btnController',
controllerAs: 'vm',
replace: true,
transclude: true,
template:
'<button ng-disabled="vm.isDisabled">'
+ '<span ng-hide="vm.isClicked">{{label}}</span>'
+ '<div class="spinner" ng-show="vm.loading">'
+ '<span class="bounce1"></span>'
+ '<span class="bounce2"></span>'
+ '<span class="bounce3"></span>'
+ '</div>' +
'</button>'
};
return directive;
}
查看
<button-spinner class="btn btn-primary btn-block btn-lg"
type="submit"
ng-click="vm.notifyMe($event)"
loading="vm.isLoading"
label="Notify Me"
available="vm.notify.is"
id="notifyMeBtn"></button-spinner>