Заменить ng-include node на шаблон?
Новое в angular. Возможно ли заменить на ng-include node на содержимое включенного шаблона? Например, с помощью:
<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>
Ответы
Ответ 1
У меня была такая же проблема, и мне все же хотелось, чтобы функции ng-include включали динамический шаблон. Я создавал динамическую панель инструментов Bootstrap, и мне нужна была более чистая разметка для стилей CSS, которые будут правильно применяться.
Вот решение, которое я придумал для тех, кто заинтересован:
HTML:
<div ng-include src="dynamicTemplatePath" include-replace></div>
Пользовательская директива:
app.directive('includeReplace', function () {
return {
require: 'ngInclude',
restrict: 'A', /* optional */
link: function (scope, el, attrs) {
el.replaceWith(el.children());
}
};
});
Если это решение было использовано в примере выше, установка scope.dynamicTemplatePath в test.html приведет к желаемой разметке.
Ответ 2
Итак, благодаря @user1737909, я понял, что ng-include - это не путь. Директивы - лучший подход и более явный.
var App = angular.module('app', []);
App.directive('blah', function() {
return {
replace: true,
restrict: 'E',
templateUrl: "test.html"
};
});
В html:
<blah></blah>
Ответ 3
У меня была та же проблема, моя таблица сторонних css CSS не понравилась дополнительный DOM-элемент.
Мое решение было суперпростым. Просто переместите ng-include 1 вверх. Поэтому вместо
<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>
Я просто сделал:
<md-sidenav flex class="md-whiteframe-z3" md-component-id="left" md-is-locked-open="$media('gt-md')" ng-include="myService.template">
</md-sidenav>
Я уверен, что это будет работать в большинстве ситуаций, даже если технически это не то, о чем спрашивает вопрос.
Ответ 4
Другой альтернативой является создание собственной простой директивы replace/include, например.
.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;
}
};
});
Затем это будет использоваться следующим образом:
<div my-replace="test.html"></div>
Ответ 5
Это правильный способ замены детей
angular.module('common').directive('includeReplace', function () {
return {
require: 'ngInclude',
restrict: 'A',
compile: function (tElement, tAttrs) {
tElement.replaceWith(tElement.children());
return {
post : angular.noop
};
}
};
});
Ответ 6
Следующая директива расширяет функциональные возможности директивы ng-include.
Он добавляет прослушиватель событий для замены исходного элемента, когда контент готов и загружен.
Используйте его оригинальным способом, просто добавьте атрибут "replace":
<ng-include src="'src.html'" replace></ng-include>
или с обозначением атрибута:
<div ng-include="'src.html'" replace></div>
Вот директива (не забудьте включить модуль include-replace в качестве зависимости):
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();
};
});
}
}
};
});
Ответ 7
Я бы пошел с более безопасным решением, чем тот, который предоставил @Brady Isom.
Я предпочитаю полагаться на параметр onload
, заданный ng-include
, чтобы убедиться, что шаблон загружен, прежде чем пытаться удалить его.
.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());
};
}
};
}])
Нет необходимости в второй директиве, поскольку все обрабатывается в пределах первой.