check if directive with given name exists, angularjs

1k Views Asked by At

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()

0

There are 0 best solutions below