7

I have the following code:

app.directive('mySample', function($compile) {
    return {
        //template:"<input type='text' ng=model='sampleData'/> {{sampleData}} <br/>"
        link: function(scope, element, atts, controller) {
            var markup = "<input type='text' ng=model='sampleData'/> {{sampleData}} <br/>";  
            angular.element(element).html($compile(markup)(scope));
            console.log($compile(markup)(scope));
        }
    };
});

And I would expect it to generate an input, some span that's coupled via the scope and a break. However I get this output:

[[object HTMLInputElement], [object HTMLSpanElement], [object HTMLBRElement]]

I also tried the template, in comment here, separately and then commenting out the link part. That generates the input and break elements but not the span that shows the coupled model input sampleData.

I have a non-working sample at http://jsfiddle.net/KvdM/nwbsT/ that demonstrates it.

5 Answers 5

15

Try this:

element.html(markup);
$compile(element.contents())(scope);
Sign up to request clarification or add additional context in comments.

3 Comments

How would I log the sampleData?
{{sampleData}} does not work because you wrote ng=model instead of ng-model :)
Depending on the nature of which you're compiling, if you're coming from a non-angular event, it may require a scope.$apply() in order for your template to be rendered.
10

Running the function returned by the $compile service gives you DOM elements rather than html. So you need to insert them into your page using append (or equivalent):

angular.element(element).append($compile(markup)(scope));

3 Comments

That shows already the input but doesn't make the {{sampleData}} work.
How does one replace the contents of the element? This adds to it rather.
probably just change "append" to "replaceWith" (I've not tried it)
1

Maybe the easiest way is to use a hard-coded template rather than a dynamic generated one

<div ng-app="myApp">
    <my-sample sample-data="'test'"></my-sample>
</div>

var app = angular.module('myApp', []);

app.directive('mySample', function ($compile) {
    return {
        restrict: 'E',
        scope: {
            sampleData: '=sampleData'
        },
        template: "<input type='text'/> {{sampleData}} <br/>",
    };
});

FIDDLE

2 Comments

It renders out the input but not the {{sampleData}} getting updated. It keeps on showing test.
That is the data passed in in HTML.
-1

Depends on what kind of data should to be compiled, some times Angular returns a comment node type.

The relevant node that we want to use is the next() (its first sibling).

var tpl = '<div class="myWidget" ng-include="'templates/myWidget.html'"></div>;
var _myWidget = $compile(tpl)(scope);
var myWidget = null;

scope.$on('$includeContentLoaded', function () {
    myWidget = _myWidget.next();
});

Comments

-1

You just needed to add the jquery to use ".html" and fixed the naming of ng-model

1 Comment

How do you mean? Can you provide a jsfiddle or relevant code sample?

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.