Ng-include düğümü şablonla değiştirilsin mi?


85

Açısaldan yeni bir tür. Ng-include düğümünü dahil edilen şablonun içeriği ile değiştirmek mümkün müdür ? Örneğin:

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

Oluşturulan 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>

Ama istediğim şey:

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

1
'test.html'url yerine şablon kullanmak için tek tırnak işaretlerini kaldırın
charlietfl

1
ng-include için dokümanın yorumlarını okurken, dizeyi şablon için tek tırnak işaretleriyle ve url olmadan çevreliyor gibi görünüyor. Ayrıca, ilgili
yığın aşımı

belgeleri okuyorsunuz ve geriye doğru bağlantı oluşturduğunuz
yayınlar

Yanıtlar:


134

Aynı sorunu yaşadım ve yine de ng-include özelliklerinin dinamik bir şablon içermesini istedim. Dinamik bir Bootstrap araç çubuğu oluşturuyordum ve CSS stillerinin doğru şekilde uygulanması için daha temiz bir işaretlemeye ihtiyacım vardı.

İşte ilgilenenler için bulduğum çözüm:

HTML:

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

Özel Direktif:

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

Yukarıdaki örnekte bu çözüm kullanıldıysa, kapsam.dynamicTemplatePath'in 'test.html' olarak ayarlanması istenen işaretlemeyle sonuçlanacaktır.


Açısal v1.2 + gerektirir
colllin

Bu yanıta benzer bir soruda başvurdum
Peter V. Mørch

Bu, açısal 1.2.5+ için çalışır. 1.2.4 için, bir ng içeren diğerini içeren bir ng varsa, başarısız olur. # 5247 yüzünden tahmin ediyorum ama emin değilim. Değişiklik günlüğünü kendiniz görün . İşte bu sorunu 1.2.4 ile gösteren bir Plunkr (açısal 1.2.5'e değiştirin ve işe yaradığını görün! :-)
Peter V.Mørch

9
Böyle bir DOM manipülasyonunun oldukça zahmetli olduğuna dikkat edin. Dahil edilen şablonun kök öğesi ng-tekrar gibi bir şey kullanıyorsa sorun vardır. DOM'a sonuç ekleyemez.
Guria

1
Lütfen buna cevabıma bakın, bu başarısız olacak çünkü ön bağlantı işlevi zaten alt öğelerde çalışacak.
Sai Dubbaka

28

@ User1737909'a teşekkürler, ng-include'in gidilecek yol olmadığını anladım. Direktifler daha iyi bir yaklaşımdır ve daha açıktır.

var App = angular.module('app', []);

App.directive('blah', function() {
    return {
        replace: true,
        restrict: 'E',  
        templateUrl: "test.html"
    };
});

Html olarak:

<blah></blah>

2
Teşekkürler! bir ng-include çözümü arıyordu ancak bu, direktiflerin daha iyi olduğunu anlamama yardımcı oldu
Matt Kim

replace:trueŞablonlarda kullanımdan kaldırılmak üzere işaretlendiğini unutmayın . Kullanımdan kaldırılma durumu nedeniyle bu çözümü kullanmaktan kaçınırdım.
Peter V.Mørch

@ PeterV.Mørch Teşekkürler. İlgilenenler için bu commit: github.com/angular/angular.js/commit/… . Karmaşıklığı nedeniyle (ve belki de başka nedenlerle) kullanımdan kaldırılmış gibi görünüyor.
SunnySydeUp

15

Ben de aynı sorunu yaşadım, 3. taraf css stil sayfam fazladan DOM öğesini beğenmedi.

Benim çözümüm süper basitti. Ng-include 1'i yukarı hareket ettirin. Yani yerine

<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>

Ben basitçe yaptım:

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

Bahse girerim bu çoğu durumda işe yarayacaktır, soru teknik olarak sorulduğu şey olmasa da.


10

Diğer bir alternatif de kendi basit replace / include direktifinizi yazmaktır, ör.

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

Bu daha sonra aşağıdaki gibi kullanılacaktır:

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

9

Bu, çocukları değiştirmenin doğru yolu

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

4
Dahil edilen kısmi html'im biraz ng-tekrarı aldı ve bunları çözen tek cevap bu! Çok teşekkürler.
Saad Benbouzid

İşlev içeriğini konumundan konumuna taşımam compilegerekiyordu linkçünkü derleme aşamasında öğem boştu.
itachi

3

Aşağıdaki yönerge, ng-include yerel yönergenin işlevselliğini genişletir.

İçerik hazır ve yüklendiğinde orijinal öğeyi değiştirmek için bir olay dinleyicisi ekler.

Bunu orijinal şekilde kullanın, sadece "değiştir" özelliğini ekleyin:

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

veya nitelik gösterimi ile:

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

Yönerge şu şekildedir (bağımlılık olarak 'dahil et-değiştir' modülünü eklemeyi unutmayın):

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

2

@Brady Isom tarafından sağlanan çözümden daha güvenli bir çözümle giderdim.

Kaldırmaya çalışmadan önce şablonun yüklendiğinden emin olmak için onloadtarafından verilen seçeneğe güvenmeyi tercih ederim 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());
            };
        }
    };
}])

Her şey birincisinde ele alındığı için ikinci bir direktife gerek yok.


açısal 1.5 ile yönerge öğesinin ilk alt öğesinin bir yorum olduğuna dikkat edin. Bu yüzden, ng-include elemanını aldığımdan ve ardından çocuklarıyla değiştirdiğimden emin oldum: let ngInclude = angular.element( element[ 0 ].querySelector( 'ng-include' ) ); ngInclude.replaceWith( ngInclude.children() );
Mattijs
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.