用模板替换 n- 包含节点?

刚开始有点瘦。有没有可能 更换的 ng-include 节点包含所包含的模板的内容?例如:

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

生成的 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>

但我想要的是:

<div ng-app>
<script type="text/ng-template" id="test.html">
<p>Test</p>
</script>
<p>Test</p>
</div>
52721 次浏览

So thanks to @user1737909, I've realized that ng-include is not the way to go. Directives are the 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>

I had this same issue and still wanted the features of ng-include to include a dynamic template. I was building a dynamic Bootstrap toolbar and I needed the cleaner markup for the CSS styles to be applied properly.

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

HTML:

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

Custom Directive:

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

If this solution were used in the example above, setting scope.dynamicTemplatePath to 'test.html' would result in the desired markup.

Another alternative is to write your own simple replace/include directive e.g.

    .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;
}
};
});

This would then be used as follows:

<div my-replace="test.html"></div>

I had the same problem, my 3rd party css stylesheet didn't like the extra DOM-element.

My solution was super-simple. Just move the ng-include 1 up. So 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 simply 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 bet this will work in most situations, even tho it technically isn't what the question is asking.

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

I prefer to rely on the onload option given 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());
};
}
};
}])

No need for a second directive since everything is handled within the first one.

This is the correct way of replacing the children

angular.module('common').directive('includeReplace', function () {
return {
require: 'ngInclude',
restrict: 'A',
compile: function (tElement, tAttrs) {
tElement.replaceWith(tElement.children());
return {
post : angular.noop
};
}
};
});

Following directive extends ng-include native directive functionality.

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

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

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

or with attribute notation:

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

Here is the directive (remember to include 'include-replace' module as 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();
};
});
}
}
};
});