Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm loading content from a database directly into a view and I'd like to compile it so angular code will executes as if it's loaded via a standard template.

What I don't quite understand is how I can compile the HTML that I'm loading from the database. When I try to use $compile it always errors out with an indexOf issue.

Error: [$parse:lexerr] Lexer Error: Unexpected next character  at columns 1415-1415 [#] 
in expression [<p>Introducing XXX featuring Something great. Along with the already famous World <strong>Approach</strong>….

From what I can see from other comments, it seems to be that $compile only works with existing DOM elements, but in my case the new SCE stuff makes me work extra hard to get the html into the view without stripping out the angular code. Only thing I can think of is maybe use a watch somehow to compile every time the content changes? Could this be done via a directive some how?

This plunker shows SCE and how to get HTML into the view without stripping out the angular code (e.g. ng-click). http://plnkr.co/edit/C0ij2j2NxGZl6NaOdW8c?p=preview. Look at the second example that uses sce.trustAsHtml(). How can I extend this to then compile the code so the ng-click works?

Thanks in advance.

share|improve this question

1 Answer 1

up vote 7 down vote accepted

Turns out that I don't need to worry about SCE if I compile the content itself. So instead of ng-bind-html, I use the exact directive found in $compile (http://docs.angularjs.org/api/ng.$compile) to put the HTML in place and compile it at the same time.

To display the compiled content:

<div compile="content.description"></div> instead of <div ng-bind-html="content.description"></div>

.directive('compile', function($compile) {
// directive factory creates a link function
return function(scope, element, attrs) {
    scope.$watch(
        function(scope) {
             // watch the 'compile' expression for changes
            return scope.$eval(attrs.compile);
        },
        function(value) {
            // when the 'compile' expression changes
            // assign it into the current DOM
            element.html(value);

            // compile the new DOM and link it to the current
            // scope.
            // NOTE: we only compile .childNodes so that
            // we don't get into infinite loop compiling ourselves
            $compile(element.contents())(scope);
        }
    );
};
});
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.