Replace ng-include node with a template?

New in angular. Is it possible to replace the ng-include node with the contents of the included template? For example, using:

<div ng-app> <script type="text/ng-template" id="test.html"> <p>Test</p> </script> <div ng-include src="'test.html'"></div> </div> 

Generated html:

 <div ng-app> <script type="text/ng-template" id="test.html"> <p>Test</p> </script> <div ng-include src="'test.html'"> <span class="ng-scope"> </span> <p>Test</p> <span class="ng-scope"> </span> </div> </div> 

But I want:

 <div ng-app> <script type="text/ng-template" id="test.html"> <p>Test</p> </script> <p>Test</p> </div> 
+73
angularjs
May 11 '13 at 11:33
source share
7 answers

I had the same problem and still wanted the ng-include functions to include a dynamic template. I was creating a dynamic Bootstrap toolbar, and I needed cleaner markup for CSS styles that would apply correctly.

Here is the solution I came up with for those interested:

HTML:

 <div ng-include src="dynamicTemplatePath" include-replace></div> 

User directive:

 app.directive('includeReplace', function () { return { require: 'ngInclude', restrict: 'A', /* optional */ link: function (scope, el, attrs) { el.replaceWith(el.children()); } }; }); 

If this solution was used in the example above, setting scope.dynamicTemplatePath to test.html will result in the desired markup.

+122
Jan 03 '14 at 20:57
source share

So thanks to @ user1737909, I realized that ng-include is not the way to go. Directives are a better approach and more explicit.

 var App = angular.module('app', []); App.directive('blah', function() { return { replace: true, restrict: 'E', templateUrl: "test.html" }; }); 

In html:

 <blah></blah> 
+27
May 12 '13 at 1:49
source share

I had the same problem, my third-party CSS css table didn't like the extra DOM element.

My decision was super simple. Just move ng-include 1 up. Therefore, instead of

 <md-sidenav flex class="md-whiteframe-z3" md-component-id="left" md-is-locked-open="$media('gt-md')"> <div ng-include="myService.template"></span> </md-sidenav> 

I just did:

 <md-sidenav flex class="md-whiteframe-z3" md-component-id="left" md-is-locked-open="$media('gt-md')" ng-include="myService.template"> </md-sidenav> 

I am sure that this will work in most situations, even if technically this is not what the question asks.

+14
Feb 01 '15 at 21:29
source share

Another alternative is to create your own simple replace / include directive, for example.

  .directive('myReplace', function () { return { replace: true, restrict: 'A', templateUrl: function (iElement, iAttrs) { if (!iAttrs.myReplace) throw new Error("my-replace: template url must be provided"); return iAttrs.myReplace; } }; }); 

Then it will be used as follows:

 <div my-replace="test.html"></div> 
+10
Aug 30 '14 at 22:25
source share

This is the right way to replace children.

 angular.module('common').directive('includeReplace', function () { return { require: 'ngInclude', restrict: 'A', compile: function (tElement, tAttrs) { tElement.replaceWith(tElement.children()); return { post : angular.noop }; } }; }); 
+9
Nov 03 '15 at 20:02
source share

The following directive extends the functionality of the ng-include directive.

It adds an event listener to replace the original item when the content is ready and loaded.

Use it in the original way, just add the "replace" attribute:

 <ng-include src="'src.html'" replace></ng-include> 

or with attribute designation:

 <div ng-include="'src.html'" replace></div> 

Here is the directive (don't forget to include the include-replace module as a dependency):

 angular.module('include-replace', []).directive('ngInclude', function () { return { priority: 1000, link: function($scope, $element, $attrs){ if($attrs.replace !== undefined){ var src = $scope.$eval($attrs.ngInclude || $attrs.src); var unbind = $scope.$on('$includeContentLoaded', function($event, loaded_src){ if(src === loaded_src){ $element.next().replaceWith($element.next().children()); unbind(); }; }); } } }; }); 
+3
May 26 '16 at 14:59
source share

I would go with a safer solution than the one provided by @Brady Isom.

I prefer to rely on the onload parameter specified by ng-include to make sure the template is loaded before trying to remove it.

 .directive('foo', [function () { return { restrict: 'E', //Or whatever you need scope: true, template: '<ng-include src="someTemplate.html" onload="replace()"></ng-include>', link: function (scope, elem) { scope.replace = function () { elem.replaceWith(elem.children()); }; } }; }]) 

There is no need for a second directive, since everything is processed within the first.

+2
Jul 29 '15 at 12:48
source share



All Articles