0

I'm trying to create a directive that will work against xml that i am injecting into the dom via a service.

Here is my a relatively reduced example, having removed the async service call for data and also the template: jsBin - transforming elements using directive

Everything works well with regard getting my post elements' header attribute into an h2 tag but it is leaving a element within my page which will fail for some browsers.

to clarify, this is what i get:

    <post class="ng-isolate-scope ng-scope" heading="test heading">
      <div class="ng-scope">
        <h2 class="ng-binding">test heading</h2>
        <div>test</div>
      </div>
    </post>

and this is what i would expect:

    <div class="ng-scope">
      <h2 class="ng-binding">test heading</h2>
      <div>test</div>
    </div>
Tom Haywood
  • 123
  • 2
  • 7

2 Answers2

2

You aren't using template correctly in your directive. Your link function should not applying your template as you are in the example code.

    var linker = function(scope, element, attrs) {

        var template = getTemplate();

        element.html(template);

        $compile(element.contents())(scope);
    };

Instead of that, just do this:

    return {
        restrict: 'E',
        replace: true,
        scope: {
            heading: '@'
        },
        template: '<div><h2>{{heading}}</h2><div>test</div></div>'
    };

In your post directive. 'replace: true' will not impact anything if you are compiling and manipulating the DOM yourself.

At the same time, though, I have no idea what your compile directive is for and why you have a factory that returns an HTML string. All of that code looks like it could be reduced to a single directive. I can't really comment on what you're trying to do, but once you start using $compile all over the place, odds are you aren't doing things the 'Angular way'.

Adam
  • 1,143
  • 7
  • 7
  • Thanks for the well structured answer Adam, yeh sorry about the example it has been reduced somewhat. my service actually makes an asynchronous call for data and from within my linker function i am dynamically loading the template and so the $compile piece occurs on success of the getTemplate call (i believe i need the compile pieces due to the service calls for both template and dom injection) – Tom Haywood Oct 15 '13 at 19:54
  • In that case, you should still use my answer. Whatever component in your code is making an asynchronous call should return a promise, which can directly be bound to in your template. It will automatically be resolved on the view for you by Angular. Using the $compile service in your link function is not necessary. – Adam Oct 15 '13 at 20:27
2

I think Adam's answer is the better route, but alternatively and easier if you include jquery you can do this in your link function:

 var e =$compile(template)(scope);
 element.replaceWith(e);
lucuma
  • 18,247
  • 4
  • 66
  • 91