I'm trying to wrap a button with a directive that will disable it according to the response from an external service. However, I need to preserve the original ng-disabled
value (if any) of the button.
I manage to get this done by changing the attribute ngDirective
I receive in the link function, however, this does not change the element in the DOM, which prevents me from testing it properly.
If I try to change the DOM element (without changing the attribute) it doesn't work at all. Changing both will not solve the testing problem, since the test will only be able to check the one thing that doesn't make a difference.
Here's a working POC:
var app = angular.module('MyApp', []);
app.service('outer', function() {
var disabled = false;
this.isDisabled = function() {
return disabled;
};
this.toggleDisabled = function() {
disabled = !disabled;
};
});
app.controller('MyCtrl', function($scope, outer) {
$scope.toggleOuter = function() {
outer.toggleDisabled();
};
$scope.isDisabled = outer.isDisabled;
$scope.inner = false;
});
app.directive('myButton', function() {
return {
restrict: 'E',
transclude: true,
replace: true,
controller: function($scope, outer) {
$scope.isDisabled = outer.isDisabled;
},
scope: {
},
template: '<button ng-transclude></button>',
link: {
post: function(s, e, a) {
var disabled = "isDisabled(" + a.actionName + ")";
if (a.ngDisabled) {
disabled += " || " + a.ngDisabled;
}
a.ngDisabled = disabled;
//e.attr('ng-disabled', disabled);
}
}
};
});
button[disabled] {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="MyApp" ng-controller="MyCtrl">
<div><button ng-click="toggleOuter()">Toggle outer</button></div>
<div><button ng-click="inner = !inner">Toggle inner</button></div>
<div><my-button ng-disabled="inner" action-name="test-action">BUTTON</my-button></div>
</div>
If I replace the line: a.ngDisabled = disabled;
With: e.attr('ng-disabled', disabled);
The DOM changes, I can test it, but it doesn't work.
Can someone explain what exactly is going on with ng-disabled
that causes this ?