dmackerman
dmackerman

Reputation: 2966

Dynamic template in directive based on attributes?

Ive seen a bunch of questions pretty similar to this, but I'm new to Angular so they aren't quite making sense. Here's my sitaution:

I have a directive defined:

robus.directive("titlebar", function() {
  return {
    restrict: "E",
    scope: { title: '@title' },
    template: "<header class='bar-title'><h1 class='title'>{{title}}</h1></header>",
    replace: true
  }
});

I use this directive like this:

<titlebar title="{{workout.name}}"></titlebar>

Ideally, I want to add optional attributes into this, like:

<titlebar title="{{workout.name}}" editButton="true" closeButton="true"></titlebar>

How do I handle these in the template definition? I've been reading about a $compile() function that I need to override, but haven't been clear on how to do so. The templates are just simple strings, so I feel like I can just do them inline versus referencing them as separate files.

Thanks!

Upvotes: 3

Views: 2167

Answers (1)

S McCrohan
S McCrohan

Reputation: 6693

Make them accessible within the directive by adding them to the scope statement, just as you have the title. Then add the buttons to the template, and conditionalize them like so:

robus.directive("titlebar", function() {
  return {
    restrict: "E",
      scope: { title: '@title', edit: '@editButton', cancel: '@cancelButton' },
      template: "<header class='bar-title'><h1 class='title'>{{title}}</h1><span ng-show='edit'>Edit</span><span ng-show='cancel'>Cancel</span></header>",
    replace: true
  }
});

<titlebar title="{{workout.name}}" edit-button="true" cancel-button="false"></titlebar>

Note that it's editButton in the directive and edit-button in the HTML; there's a built-in conversion from hyphenated to camel-case that will bite you if you're not aware of it.

Also, I recommend the use of transclude here, as I think it will read a bit more cleanly:

robus.directive("titlebar", function() {
  return {
    restrict: "E",
      scope: { edit: '@editButton', cancel: '@cancelButton' },
      template: "<header class='bar-title'><h1 class='title' ng-transclude></h1><span ng-show='edit'>Edit</span><span ng-show='cancel'>Cancel</span></header>",
    transclude: true,
      replace: true
  }
});

<titlebar edit-button="true" cancel-button="false">{{workout.name}}</titlebar>

Upvotes: 3

Related Questions