AngularJS Is there a way to dynamically register a directive after boostrap

I want to dynamically load and compile a directive some time after the application is loaded.

As with a button click, I want to run code similar to this one:

app.directive('dynamicDirective',
    ['$compile', '$timeout', 'searchBuilderFactory',
    function ($compile, $timeout, searchBuilder) {
        return function (scope, element, attrs) {
            scope.$watch(attrs.truBindNgHtml, function (newValue, oldValue) {
                if (newValue === oldValue) return;
                var directiveName = 'advanced' + newValue;

                app.directive(directiveName, function() {
                    return {
                      template: 'Name: {{customer.name}} Address: {{customer.address}}'
                    };
                }); 

                var html = '<' + directiveName + '>' + '</' + directiveName + '>';

                element.html(html);
                $compile(element.contents())(scope);
            });
        };
}]);  

      

Here's a partially working example: Fiddle

+3


source to share


1 answer


You got it almost right, I'm not entirely sure about the part of the controller that does, however you have some problems.

  • The directive is registered with a penalty, but the constraint is a problem, you have an element constraint that you need to be explicit about, for example restrict:'E'

  • When looking at attributes, don't use scope.$watch

    instead of using attrs.$observe

    , in your case, attrs.$observe('dynamicDirective', fn)

    or use scope binding with scope:{dynamicDirective:'@'}

    anc usescope.$watch('dynamicDirective', fn)

  • Inorder for passing values ​​and its visible use is interpolation when directive is consumed when using attr binding or scope with @

    , if you are using 2-way =

    you don't need that.

Try: -



function ($compile) {

    return function (scope, element, attrs) {
        attrs.$observe('dynamicDirective', function (v, ov) {
            if (!v) return; //If no value do nothing
            var directiveName = 'advanced' + v;

            app.directive(directiveName, function () {
                return {
                    template: '<p>Blah</p>',
                    restrict: 'E'
                };
            });

            var newEl = '<' + directiveName + '>' + '</' + directiveName + '>';
            element.html(newEl); //or element.append(); if you want to add upon
            $compile(element.contents())(scope);

        });
    }
}]);

      

Plnkr

+1


source







All Articles