2

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.

1 Answer 1

7

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

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.