My custom service and directive work together to remove DOM elements based on specific criteria.
The service checks a string parameter, while the directive removes the element it's attached to if the check fails.
This functionality is supported in IE11, Edge, Chrome, and FireFox. However, I'm struggling to replicate this behavior in my tests.
Check out the working code on JSBin
Here's an example of the service and its provider:
class PermissionService {
constructor(permissions) {
this.permissions = permissions;
}
addPermissions(permissions) {
this.permissions = this.permissions.concat(permissions);
}
has(permission) {
return this.permissions.indexOf(permission) !== -1;
}
}
class PermissionProvider {
constructor() {
let _permissions = [];
this.setPermissions = (permissions) => {
_permissions = _permissions.concat(permissions);
};
this.$get = () => {
return new PermissionService(_permissions);
}
}
}
Next, we have the directive implementation within an Angular module:
angular.module('PermissionTest', [])
.directive('hasPermission', ['permission', '$compile', (service, $compile) => {
return {
restrict: 'A',
priority: 1,
terminal: true,
compile: (element, attrs) => {
let permission = attrs.hasPermission;
if (service.has(permission)) {
attrs.$set('hasPermission', null);
return (scope, element) => {
$compile(element)(scope);
}
} else {
element.remove();
}
}
}
}])
.provider('permission', PermissionProvider)
.config(['permissionProvider', (provider) => {
provider.setPermissions(['yes']);
}]);
With this directive, removing elements from the DOM becomes straightforward:
<!-- Not removed -->
<div has-permission="yes">Is not removed</div>
<!-- Removed -->
<div has-permission="no">Is removed</div>
I've set up a test scenario that should pass but doesn't. I suspect the issue lies in the directive recompiling itself, even though it should happen during scope.$digest()
. Any help with debugging would be appreciated.
let provider;
let service;
describe('directive: has-permission', () => {
beforeEach(module('permissionChecker', (permissionProvider) => {
provider = permissionProvider;
provider.setPermissions(['crm.check.r', 'crm.check.c']);
}));
beforeEach(inject((permission) => {
service = permission;
}));
});
describe('if directive is not valid', () => {
let scope;
let element;
beforeEach(inject(($rootScope, $compile) => {
scope = $rootScope.$new();
element = `<div>
<div has-permission="crm.not.r"></div>
<div has-permission="crm.check.r"></div>
</div>`;
element = $compile(element)(scope);
scope.$digest();
}));
it('should remove one child element', () => {
let test = angular.element(element).children();
expect(test.length).toBe(1);
});
});