Is there a way of checking if an directive in angular exists?
What I want to do, oder better what I have: A Collection of 'protocols', which share some similarities, such as: name, created by, last edited, comment etc., but they all have special fields.
I have this one directives which matches with all those protocols. Showing the name and all the things which all the protocol have in common. Within this directive I want to check if a special (more specific) view of the given protocol is available. In my case I call it "CompactView". The CompactView will give more detailed information of this protocol, it should be displayed within the actual directives. So a nested directive - no big deal.
My first approched worked fine, I had an array which had the protocol name as key, and directive html element (string) as value:
let decider = {
'cardiovascular_function': '<hcd-Cardiovascular-Function-Compact-View protocol="protocol"/>'
};
//use suitable directive
let protocolDirective = decider[scope.protocol.name];
let templateHook = angular.element(element).find('.extend-protocol-info')[0];
//use base template
//hooks protocol directive into template if possible
if (typeof protocolDirective != 'undefined') {
let compiled = $compile(angular.element(protocolDirective))(scope);
angular.element(templateHook).html(compiled);
scope.defaultTxt = false;
}else{
scope.defaultTxt = true;
}
If no key exited within the decider array I will display some default txt explaining, that there is no CompactView available.
The application will likely grow, and a lot of protocols will follow, so when ever someone creates a protocol the decider array needs to be extend. Prone to failure, and it would be much nicer if I can just check if a directive with some name exists and compile it.
My new approached look like the following:
let protocolName = scope.protocol.name;
let directiveName = 'hcd' + _.capitalize(_.camelCase(protocolName)) + 'CompactView';
//example: <hcd-Cardiovascular-Function-Compact-View protocol="protocol"/>
console.log(directiveName);
console.log($injector.has(directiveName));
try {
console.log(angular.module('hcdProtocol').directive(directiveName));
} catch (err) {
console.log(err);
}
//check if directive for given protocol exists
if ($injector.has(directiveName)) {
scope.defaultTxt = false;
let templateHook = angular.element(element).find('.extend-protocol-info')[0];
let protocolDirective = '<hcd-' + _.kebabCase(protocolName) + '-Compact-View protocol="protocol" />';
let compiled = $compile(angular.element(protocolDirective))(scope);
angular.element(templateHook).html(compiled);
} else {
//display default if no compact view exists
scope.defaultTxt = true;
}
So $injector.has is not working, since directives are not registered within $provide. Redeclaring and checking for errors, the try catch block, is not working either.
I'm currently trying to understand $compileProvider, somewhere within angular is the information which directive exist, I would love to find it.
Any ideas or suggestions, on how to fix this "generic directive" approach? Maybe my concept with this nested directives is wrong, and there is a much simpler approach?
Both code blocks are within the link function of directive()