MrPlow
MrPlow

Reputation: 1467

Angular attribute directive - add an ng-repeat below current directive

If I had an attribute directive, for example something like this:

<select multiple ... ng-model="ctrl.model" custom-directive="ctrl.customModel" />

where let's say that ngModel and customModel are arrays. Is there a way I can, within the directive's code, add a piece of html below the directives element which could have access to the scope of the directive and be able to reference the customModel so that in the end it looks something like this:

<select multiple ... ng-model="ctrl.model" custom-directive="ctrl.customModel" />
<div><!-- this code gets added by the custom-directive directive and uses it's scope -->
    <span ng-repeat="item in customDirectiveCtrl.customModel" ng-bind="item.property"></span>
</div>

I know I can add html manually using jqLite, however this html doesn't have access to directive scope. The reason I don't want to convert the custom-directive directive from attribute directive to element directive is because it makes it way more difficult to add attributes such as id, name, required, disabled,... to underlying template elements (in the case of this example, a select element)

EDIT: as requested here's an example of how to add an element after the directives element:

{
  restrict: 'A',
  require: 'ngModel',
  scope: { customModel: '=customDirective' },
  link: function(scope, element, attrs, ngModel) {
     //element.after('<div></div>'); //this adds a div after the directives element
     element.after('<div><span ng-repeat="item in customModel" ng-bind="item.property"></span></div>'); //this will add the html in the string, but will not interpret the angular directives within since (i assume) that it is not bound to any scope.
  }
}

Any angular component/directive added like this will not work properly or at all.

Upvotes: 0

Views: 512

Answers (1)

mcgraphix
mcgraphix

Reputation: 2733

If you are injecting new HTML into the page in your directive, and you need that HTML to use angular directives (ng-repeat, ng-bind, etc) then you will need to use the $compile service to make angular aware of your new DOM elements. In your case, you would inject the $compile service into your directive and then use it like this:

 link: function(scope, element, attrs, ngModel) {
      //create the new html
      var newElement = angular.element('<div><span ng-repeat="item in customModel" ng-bind="item.property"></span></div>');    
      //compile it with the scope so angular will execute the directives used
      $compile(newElement)(scope); //<-this is the scope in your link function so the "customModel" will be accessible. 
      //insert the HTML wherever you want it
      element.after(newElement); 
}

Upvotes: 1

Related Questions