23

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.

3

5 Answers 5

20

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));
  });
});
Sign up to request clarification or add additional context in comments.

Comments

12

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.

1 Comment

Nice answer thank you. You just have forget to inject $rootScope inside the function ;)
5

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);
  });
});

Comments

1

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

2 Comments

What is element1 and 2 ?
Elem1 is the​ source element, where you have the html structure you want angular to compile. Elem2 is the place where you will put your new compiled html.
1

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

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.