Coś nowego w kanciastym. Czy można zamienić węzeł ng-include na zawartość dołączonego szablonu? Na przykład z:
<div ng-app>
<script type="text/ng-template" id="test.html">
<p>Test</p>
</script>
<div ng-include src="'test.html'"></div>
</div>
Wygenerowany html to:
<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>
Ale ja chcę:
<div ng-app>
<script type="text/ng-template" id="test.html">
<p>Test</p>
</script>
<p>Test</p>
</div>
'test.html'
szablonu zamiastOdpowiedzi:
Miałem ten sam problem i nadal chciałem, aby funkcje ng-include zawierały dynamiczny szablon. Budowałem dynamiczny pasek narzędzi Bootstrap i potrzebowałem czystszego znacznika, aby style CSS były poprawnie stosowane.
Oto rozwiązanie, które wymyśliłem dla zainteresowanych:
HTML:
<div ng-include src="dynamicTemplatePath" include-replace></div>
Dyrektywa celna:
app.directive('includeReplace', function () { return { require: 'ngInclude', restrict: 'A', /* optional */ link: function (scope, el, attrs) { el.replaceWith(el.children()); } }; });
Gdyby to rozwiązanie zostało użyte w powyższym przykładzie, ustawienie scope.dynamicTemplatePath na „test.html” spowodowałoby uzyskanie żądanego znacznika.
źródło
Dzięki @ user1737909 zdałem sobie sprawę, że ng-include nie jest właściwą drogą. Dyrektywy są lepszym podejściem i są bardziej jednoznaczne.
var App = angular.module('app', []); App.directive('blah', function() { return { replace: true, restrict: 'E', templateUrl: "test.html" }; });
W html:
<blah></blah>
źródło
replace:true
w szablonach jest oznaczony do wycofania . Unikałbym korzystania z tego rozwiązania ze względu na stan wycofania.Miałem ten sam problem, mój arkusz stylów CSS innej firmy nie podobał się dodatkowemu elementowi DOM.
Moje rozwiązanie było super proste. Po prostu przesuń ng-include 1 w górę. Więc zamiast
<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>
Po prostu zrobiłem:
<md-sidenav flex class="md-whiteframe-z3" md-component-id="left" md-is-locked-open="$media('gt-md')" ng-include="myService.template"> </md-sidenav>
Założę się, że to zadziała w większości sytuacji, nawet jeśli technicznie nie jest to, o co chodzi w pytaniu.
źródło
Inną alternatywą jest napisanie własnej prostej dyrektywy zamień / dołącz, np
.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; } }; });
Zostałoby to następnie użyte w następujący sposób:
<div my-replace="test.html"></div>
źródło
To jest właściwy sposób zastępowania dzieci
angular.module('common').directive('includeReplace', function () { return { require: 'ngInclude', restrict: 'A', compile: function (tElement, tAttrs) { tElement.replaceWith(tElement.children()); return { post : angular.noop }; } }; });
źródło
compile
dolink
, ponieważ mój element był pusty na etapie kompilacji.Poniższa dyrektywa rozszerza natywną funkcjonalność dyrektywy ng-include.
Dodaje detektor zdarzeń, aby zastąpić oryginalny element, gdy zawartość jest gotowa i załadowana.
Użyj go w oryginalny sposób, po prostu dodaj atrybut „zamień”:
<ng-include src="'src.html'" replace></ng-include>
lub z notacją atrybutu:
<div ng-include="'src.html'" replace></div>
Oto dyrektywa (pamiętaj, aby uwzględnić moduł „include-replace” jako zależność):
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(); }; }); } } }; });
źródło
Wybrałbym bezpieczniejsze rozwiązanie niż to dostarczone przez @Brady Isom.
Wolę polegać na
onload
opcji podanej przez,ng-include
aby upewnić się, że szablon jest załadowany przed próbą jego usunięcia..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()); }; } }; }])
Nie ma potrzeby stosowania drugiej dyrektywy, ponieważ wszystko jest załatwiane w ramach pierwszej.
źródło
let ngInclude = angular.element( element[ 0 ].querySelector( 'ng-include' ) ); ngInclude.replaceWith( ngInclude.children() );