Search code examples
angularjstwitter-bootstrap-3angularjs-directiveangularjs-ng-transcludetransclusion

Nested directives with transclusion


I have a set of form directives in which duplicate code can be extracted into a separate directive.

I know that I can use transclusion, but have not been able to identify any technique that allows this (element cloning or passing functions). Tutorials on pluralsight, sitepoint and few other describe extraction into a directive inside the current directive, but I have not been able to apply them to my use case.

Brief Synopsis:- Two sample directives

<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
  <div class="form-group">
    <label ng-show="visible">Input: 
      <input ng-model="person.name" type="text" required>
    </label>
    <p ng-show="!visible"> {{person.name}} </p>
  </div>
</div>

And

<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
  <div class="form-group">
    <label ng-show="visible">Input: 
      <select> <option value="volvo">Volvo</option> ....  </select>
    </label>
    <p ng-show="!visible"> {{person.name}} </p>
  </div>
</div>

I wish to condense them into directives like

<my-input-box ng-model="person.name" required></my-input-box>
<my-select-box options = "person.options"></my-select-box>

where my-input-box template is

<my-wrapper-box><input ng-model="person.name" type="text" required></my-wrapper-box>

and my-select-box template is

<my-wrapper-box><select>......</select></my-wrapper-box>

Please see this plunker: http://plnkr.co/edit/k6LWjn?p=preview

How do I extract the wrapper box so that 2-way binding is maintained with the ng-model and overriding attributes like required, bootstrap classes, validation regex, etc. in either the my-wrapper-box or the transcluded HTML element?

Many thanks to all who have read the question. I look forward to your suggestions.


Solution

  • Plunker.

    I've added the following to myInputBox directive:

    controller: function(){},
    bindToController: true,
    controllerAs: 'ctrl',
    

    and changed the html to

    <my-wrapper-box>
      <input type="text" ng-required="reqd"  ng-model="ctrl.value" />
    </my-wrapper-box>