how can we use $compile outside a directive in Angularjs

I want to use $compile in a controller inside a function and not in a directive. is it possible? I am trying the below code.

$compile('<div ng-attr-tooltip="test">Cancel</div>')(scope)

But this is throwing scope is undefined error. I tried to pass $scope inside the function but it is not working.

How would Angular know that you changed the DOM? You need to compile your html before appending it (using $compile service).

If you absolutely need access outside of a directive you can create an injector.

$(function() {
  // myApp for test directive to work, ng for $compile
  var $injector = angular.injector(['ng', 'myApp']);
  $injector.invoke(function($rootScope, $compile) {
    $('body').prepend($compile('<div ng-attr-tooltip="test">Cancel</div>')($rootScope));
  });
});

It’s worth to note, the injector in previous answer (var $injector = angular.injector(['ng', 'myApp']);) will not append compiling directive to your currently running angular app, it will create new instead.

To dynamically append new directives to your app, you should use already existed injector:

$(function() {
  angular.element(document).injector().invoke(function($rootScope, $compile) {
    $('body').prepend($compile('<div ng-attr-tooltip="test">Cancel</div>')($rootScope));
  });
});

See last paragraph in documentation.

I tried @Vaibhav Jain’s answer, with no success. After a little more digging, this is what I found to work on Angular 1.3, and jQuery:

$(function() {
  angular.element(document).injector().invoke(['$compile', function ($compile) {
    // Create a scope.
    var $scope = angular.element(document.body).scope();
    // Specify what it is we'll be compiling.
    var to_compile="<div ng-attr-tooltip="test">Cancel</div>";
    // Compile the tag, retrieving the compiled output.
    var $compiled = $compile(to_compile)($scope);
    // Ensure the scope and been signalled to digest our data.
    $scope.$digest();
    // Append the compiled output to the page.
    $compiled.appendTo(document.body);
  });
});

I did this

var SCOPE;
app_module.controller('appController', function ($scope, $compile) {
    SCOPE = $scope;
    $scope.compile = function (elem_from, elem_to) {
        var content = $compile(angular.element(elem_from))($scope);
        angular.element(elem_to).append(content);
    }
});

use like this

SCOPE.compile(elem1.content, elem2);

I recompiled my html by the following way when I was needed to recompile my html to apply the changes on the page.

Read More:   Javascript RegExp for splitting text into sentences and keeping the delimiter

It happens when I was trying to go to other link and back again to the page but for some reason the angular code was not compiling.

So I fixed this by compiling the html part of the page again at a load event.

function OnLoad() {
angular.element("form:first").injector().invoke(['$compile', function ($compile) {
    var $scope = angular.element("form:first").scope();
    $compile("form:first")($scope);
}]);
}

Below is the app declaration.

<form ng-app="formioApp" ng-controller="formioAppCtrl">

and OnLoad() function is assigned in a html element’s onload event on that page.


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Similar Posts