Reputation: 187399
In an Angular 1.4.7 app I want to programmatically compile a string of HTML, passing it a scope. This compilation is performed inside a directive, and I want to append the result of the compilation to a child of the directive's element.
I'm current attempting to do this like so:
// htmlTemplate is a string of HTML that contains expressions,
// directives, etc.
var htmlContentScope = {foo: 'foo', bar: 'bar'};
var compiledHtml = $compile(htmlTemplate)(htmlContentScope);
var htmlContentTarget = $element.find('.html-content');
htmlContentTarget.html(compiledHtml);
However this results in the following error
scope.$new is not a function
Possibly the reason for this is that htmlContentScope
is a plain-old JS object, rather than an Angular scope object?
Upvotes: 2
Views: 660
Reputation: 95754
Correct, you need to pass in an Angular Scope, not an normal object or hash. This is important so that Angular can enforce watches, keep track of the scope's ID number in internal data structures, and access the root scope.
As in the "Usage" section of the $compile docs:
Returns
function(scope, cloneAttachFn=, options=)
a link function which is used to bind template (a DOM element/tree) to a scope. Where:
- scope - A Scope to bind to.
- ...
So assuming you have access to a scope
parameter, because this is likely in a link
or postLink
function:
var htmlContentScope = scope.$new();
htmlContentScope.foo = 'foo';
htmlContentScope.bar = 'bar';
var compiledHtml = $compile(htmlTemplate)(htmlContentScope);
$element.find('.html-content').html(compiledHtml);
Of course, if this weren't in a directive or if you wanted a clean slate free of parent scope interference, you could extend the $rootScope
instead, but in a directive it's much more correct to use the scope you're given.
Upvotes: 1