0

I want to write a directive which takes advantage of custom attributes, as follows:

<plant-stages
    title="Exploration<br/>du cycle de<br/>développement<br/>de la plante"
></plant-stages>

The controller is currently as follows:

app.directive('plantStages', function () {
    return {
        restrict: 'AE',
        templateUrl: 'corn.figure.plant.stages.html',
        link: function (scope, element, attrs) {
        scope.title = attrs.title;
        }
    };
});

The partial is as follows:

<figure class="cornStages">
    <div>
        <p>{{title}}</p>
    </div>
    <div ng-repeat="stage in stages">
        <div class="stage{{stage.stage}}"></div>
        <div>
            BBCH&nbsp;: {{stage.bbch}}<br/>
            {{stage.displayName}}
        </div>
    </div>
 </figure>

The partial makes use of some scope model variables. And {{title}} should support plain HTML injection out of the view which embeds it, hence should be compiled. I tried to support this but without success.

What modification should I make to have the HTML compiled?

A bonus question: when I pass the attribute in, I create a dummy title variable in the scope that persists where it should only be local. How would one make changes to handle this?

Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95
  • you want to place HTML in a tag attribute and then use it in your directive? – Sebastian May 02 '14 at 20:37
  • Are you looking for `scope: { title: "@" }`? See [this answer](http://stackoverflow.com/a/14063373/2630455). It means title on the directive's scope is the evaluated value of the DOM attribute named `title`. – Steve Klösters May 02 '14 at 20:38
  • @stevuu : as I mentionned in the question, if I make use of scope: {} I loose the controller scope data I need to render my directive (specifically "stages") – Stéphane de Luca May 02 '14 at 21:13
  • I would use `scope: {}` to attach data from the controller's scope to the directive's scope, then. For example, `scope: { stages: "="}` with ``. The `stages` attribute then points the directive to controller data. Assuming data on the controller's scope is available in a directive is an invisible dependency, but pointing it with `scope` makes it visible. – Steve Klösters May 02 '14 at 21:17
  • When you only need direct binding for a small amount of variables in the parent scope, I'd recommend what stevuu recommends. It creates an isolated scope from your parent scope, but still allows you to modify specific attributes from within your directive. – robert.bo.roth May 02 '14 at 21:23

1 Answers1

1

If you want to wrap HTML in your custom directive take a look at the transclude option (see docs):

module.directive('myDirective', function() {
  return {
    restrict: 'E',
    transclude: true,
    template: '<div ng-transclude></div>'
  };
}); 

This enables you to place HTML within the directive tag which can be used in the template:

<div ng-controller="Controller">
  <my-directive>
    <h1>Test</h1>
  </my-directive>
</div>

In case you really want to pass HTML via an attribute use ng-bind-html. This requires the ngSanitize module:

module.directive('myDirective', function () {
  return {
    restrict: 'E',
    template: '<div ng-bind-html="title"></div>',
        scope: {
            title:'@'
        }
    };
});

I added this to your fiddle.

Sebastian
  • 16,813
  • 4
  • 49
  • 56
  • Based on all comments, I created the jsfiddle http://jsfiddle.net/stephanedeluca/QRZFs/4/ but it breaks with an issue about the parent.insertBefore @Sebastian – Stéphane de Luca May 02 '14 at 22:27
  • 2 things: 1) I need to pass many attributes with some conning tags 2) Look at the hg-repeat in the partial that does not work (nothing is written to (inside) the directive). – Stéphane de Luca May 02 '14 at 22:35
  • Actually I see in the inspector there is an issue in the fiddle (undefined for parent.insertBefore) – Stéphane de Luca May 03 '14 at 09:21
  • I overlook that you used a `ng-repeat` within the `ng-transclude` tag. Instead use e.g. `

    ` http://jsfiddle.net/3YwSn/2/
    – Sebastian May 03 '14 at 09:46
  • ok. But one of my initial issue is not yet addressed: I want to pass my html via the title attribute and being compiled (the one you rewrote as unnecessary). – Stéphane de Luca May 03 '14 at 09:53
  • Have a look to this fiddle where my experiments stand: http://jsfiddle.net/stephanedeluca/QRZFs – Stéphane de Luca May 03 '14 at 09:59
  • OK. I understand. You can use `ng-bind-html`. I will add that to the answer. – Sebastian May 03 '14 at 10:03
  • The ng-click the partial originally contained broke. I have open a new question there: http://stackoverflow.com/questions/23443573/how-to-invoke-ng-click-from-a-directive-partial – Stéphane de Luca May 03 '14 at 11:05