Himanshu Goel
Himanshu Goel

Reputation: 604

Injecting angular element from controller but not working as directive

My problem is that a html element needs to be replaced with a directive on event call. So i am calling a function in my controller on click event and appending the angular element at the desired position, that angular element is a directive so i need to do something to make it recognizable as directive. I have tried $compile but that doesn't work at controller level.

My controller Code

angular.element(document.body).append("<annotation></annotation> ");

My Directive code

app.directive("annotation", function($compile){

var linker = function(scope,element, attrs){
    element.html("Done "+attrs.content);

    if(attrs.content){

        $(element).tooltipster({
            content: $("<button class=\"btn btn-primary\">Highlight</button>"),
            animation: 'fade',
            delay: 200,
            interactive: true,
            theme: 'tooltipster-default',
            touchDevices: false,
            trigger: 'hover'
          });
    }

    $compile(element)(attrs);
}

return {
    restrict : "E",
    template: '<div class="highlightor"></div>',
    replace : true,
    link : linker,
    scope: {
        content: "="
    }
};

});

Upvotes: 2

Views: 4079

Answers (1)

musically_ut
musically_ut

Reputation: 34288

Update:: Something akin to this might work:

.controller('myController', ['$scope', '$compile', function ($scope, $compile) {
    $scope.onClick = function () {
        angular.element(document.body).append(
                $compile("<annotation></annotation>")($scope)
        );
    };
}]);

It can be made to work the way you want by injecting $compile into the controller and then doing DOM manipulation therein. However, it is not the correct approach and flouts one of the rules from Zen of Angular.

Do not do DOM manipulations in the Controller.

The Correct Way (TM), IMO, will be to have the click change a boolean flag on the $scope in the controller and then using that boolean flag to switch between the templates:

Template:

<div ng-if="!annotationVisible" ng-click="showAnnotation()">
    Click here to see annotations.
</div>
<div ng-if="annotationVisible"><annotation></annotation></div>

Controller:

$scope.annotationVisible = false;
$scope.showAnnotation = function () { $scope.annotationVisible = true; };

Upvotes: 2

Related Questions