Chad Johnson
Chad Johnson

Reputation: 21895

Custom elements inside AngularJS directive?

I'd like to avoid repeating myself with my page header as much as possible. So, I'm thinking doing something like this:

<header>
    <title>Forms</title>
    <actions>
        <action ng-click="showNewFormModal()">New Form</action>
        <action ng-click="showHelp()">?</action>
    </actions>
</header>

which would desirably result in

<div class="page-header">
    <div class="left">
        <h3>Forms</h3>
    </div>

    <div class="right">
        <a class="btn btn-default" role="button" ng-click="showNewFormModal()">New Form</a>
        <a class="btn btn-default" role="button">?</a>
    </div>

    <div class="clearfix"></div>
</div>

As you can see, <header> contains custom elements, <title>, <actions>, and <action>, which are specific to only the <header> element.

Is such a thing possible in Angular? How would I accomplish this?

Upvotes: 0

Views: 107

Answers (1)

Tom
Tom

Reputation: 7740

See this jsbin I put together which shows how it can be done with custom directives. I had trouble using the names header and title (though I'm almost positive it can be done), for the example, I've user my-header and my-title

Anyways, I've put together the first two elements, the rest will follow the same convention. You can also set up dependencies and scope on each directive, i.e. an action must be inside of an actions parent element

app.directive('myHeader', function() {
  return {
    restrict: "E",
    transclude: true,
    template: "<div class='page-header'><div ng-transclude></div></div>"
  };
});

app.directive('myTitle', function() {
  return {
    restrict: "E",
    transclude: true,
    template: "<div class='left'><div ng-transclude></div></div>"
  };
});

Your HTML will look like:

<my-header>
    <my-title>Forms</my-title>
</my-header>

And the generated HTML will look like:

<my-header>
    <div class="page-header">
        <div ng-transclude="">
            <my-title class="ng-scope">
                <div class="left">
                    <div ng-transclude="">
                        <span class="ng-scope">Forms</span>
                    </div>
                </div>
            </my-title>
        </div>
    </div>
</my-header>

Upvotes: 1

Related Questions