açısal ng-bind-html ve içindeki yönerge


95

Plunker Bağlantısı

Html'yi ona bağlamak istediğim bir öğem var.

<div ng-bind-html="details" upper></div>

Bu işe yarıyor. Şimdi, bununla birlikte, bağlı html'ye bağlı bir yönergem de var:

$scope.details = 'Success! <a href="#/details/12" upper>details</a>'

Ancak upperdiv ve çapa ile direktif değerlendirilmez. Nasıl çalıştırırım?



@Chandermani, ng-bind-html-güvenli olmayan yönergeyi tam olarak kullanmıyor, ancak filtre kullanıyor. Ama işe yarayacak, ben sadece bir filtre oluşturdum ve yönergeye geçtim. Teşekkürler!
Amitava

@SamSerious, filtreler için yaptıklarını nasıl yaptığını gösterebilir misin?
CMCDragonkai

yukarıdaki çözümler, değerin birden fazla değişikliğini işlemez daha iyi bir çözüm stackoverflow.com/a/25516311/3343425
fghibellini

Yanıtlar:


187

Ben de bu sorunla karşı karşıyaydım ve internette saatlerce araştırdıktan sonra @ Chandermani'nin çözüm olduğunu kanıtlayan yorumunu okudum. Bu kalıpla bir 'derleme' yönergesi çağırmanız gerekir:

HTML:

<div compile="details"></div>

JS:

.directive('compile', ['$compile', function ($compile) {
    return function(scope, element, attrs) {
        scope.$watch(
            function(scope) {
                // watch the 'compile' expression for changes
                return scope.$eval(attrs.compile);
            },
            function(value) {
                // when the 'compile' expression changes
                // assign it into the current DOM
                element.html(value);

                // compile the new DOM and link it to the current
                // scope.
                // NOTE: we only compile .childNodes so that
                // we don't get into infinite loop compiling ourselves
                $compile(element.contents())(scope);
            }
        );
    };
}])

Burada işleyen bir keman görebilirsiniz


1
2. satırda, yani. function(scope, element, attrs), bu üç argümandan, kapsam , öğe ve özelliklerden nereden aldınız ?
spaffy

1
@spaffy - bunlar, Angular çerçevesinin linkmülk için imzasının bir parçasıdır . linkAngular çerçeve tarafından her çağrıldığında otomatik olarak aktarılırlar . Her zaman müsait olacaklar.
Ben

1
Aferin. Aynı arama saatlerini de kurtardın. İçeriği, ng-tekrar gibi Açısal işaretlemeyi içeren SharePoint görünümü REST API'sinden alıyorum. Yönergeniz her şeyi çalıştırdı. Teşekkürler!
Phil Nicholas

Yönergeniz için teşekkürler, yaşadığım sorunları çözdü. Şimdi açısal kod derleniyor ama birçok kez. 3 nesneli bir ng tekrarı, her biri sadece 3x aynı değerlere dönüşür. Burada ne ters gidiyor?
Jason

2
$sce.trustAsHtmlBu yönerge ile "derlenecek" HTML'yi oluşturmak için başka bir işlevden kullanıyorsanız , onu kaldırmalısınız. Teşekkürler @apoplexy
Burak Tokak

36

Harika cevap vkammerer için teşekkürler. Tavsiye edebileceğim bir optimizasyon, derleme bir kez çalıştıktan sonra izlemenin kaldırılmasıdır. İzleme ifadesi içindeki $ eval, performansa ilişkin etkilere sahip olabilir.

    angular.module('vkApp')
  .directive('compile', ['$compile', function ($compile) {
      return function(scope, element, attrs) {
          var ensureCompileRunsOnce = scope.$watch(
            function(scope) {
               // watch the 'compile' expression for changes
              return scope.$eval(attrs.compile);
            },
            function(value) {
              // when the 'compile' expression changes
              // assign it into the current DOM
              element.html(value);

              // compile the new DOM and link it to the current
              // scope.
              // NOTE: we only compile .childNodes so that
              // we don't get into infinite loop compiling ourselves
              $compile(element.contents())(scope);

              // Use un-watch feature to ensure compilation happens only once.
              ensureCompileRunsOnce();
            }
        );
    };
}]);

İşte çatallı ve güncellenmiş bir keman.


Bunun için tam tersini alabilir miyim?
Sanyam Jain

bu ajax yanıtında işe yaramıyor, ancak yanıt çalışması kabul edildi
foozhan

1
Uyarı: Bu yanıt için keman işe yarıyor, ancak .directive()yanıta gönderilen koddaki kod çalışmıyor.
Phil Nicholas

bu benim için çalıştı. seçilen cevap "Hata: $ rootScope: infdig Sonsuz $ özet Döngüsü" nü tetikler
Gabriel Andrei

Açıklamaya ihtiyacınız olmamalı $eval- sadece attrs.compileizlenen anonim işlevin yerine doğrudan kullanabilirsiniz . Sadece bir dizgi ifadesi sağlarsanız, açısal $evalyine de onu çağıracaktır .
Dan King

28

Bu yönergeyi angular-bind-html-compile ekleyin

.directive('bindHtmlCompile', ['$compile', function ($compile) {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      scope.$watch(function () {
        return scope.$eval(attrs.bindHtmlCompile);
      }, function (value) {
        // Incase value is a TrustedValueHolderType, sometimes it
        // needs to be explicitly called into a string in order to
        // get the HTML string.
        element.html(value && value.toString());
        // If scope is provided use it, otherwise use parent scope
        var compileScope = scope;
        if (attrs.bindHtmlScope) {
          compileScope = scope.$eval(attrs.bindHtmlScope);
        }
        $compile(element.contents())(compileScope);
      });
    }
  };
}]);

Bunu şu şekilde kullanın:

<div bind-html-compile="data.content"></div>

Gerçekten kolay :)


1
Şöyle bir şey iletirseniz dikkatli olun: "$ kapsam.loadContent = function () {return $ sce.trustAsHtml (required ('html / main-content.html'));};" ona sonsuz özet döngüsü elde edebilirsiniz. TrustAsHtml olmadan çalışır.
Lakatos Gyula

13

Ne yazık ki yorum yapacak kadar itibarım yok.

Bunu asırlardır çalıştıramadım. ng-bind-htmlKodumu bu özel yönergeyi kullanacak şekilde değiştirdim , ancak $scope.html = $sce.trustAsHtml($scope.html)ng-bind-html'nin çalışması için gerekli olanı kaldıramadım . Bunu kaldırır kaldırmaz, derleme işlevi çalışmaya başladı.


6

$sce.trustAsHtmlBurada daha önce işlenmiş içerikle uğraşan herkes için farklı yapmam gereken şey buydu

function(scope, element, attrs) {
    var ensureCompileRunsOnce = scope.$watch(function(scope) {
            return $sce.parseAsHtml(attrs.compile)(scope);
        },
        function(value) {
            // when the parsed expression changes assign it into the current DOM
            element.html(value);

            // compile the new DOM and link it to the current scope.
            $compile(element.contents())(scope);

            // Use un-watch feature to ensure compilation happens only once.
            ensureCompileRunsOnce();
        });
}

linkFarklı bir düzen kullandığım için bu direktifin yalnızca bir kısmı. $sceHizmeti de enjekte etmeniz gerekecek $compile.


-2

Bulduğum en iyi çözüm! Kopyaladım ve tam ihtiyacım olduğu gibi çalışıyor. Teşekkürler, teşekkürler, teşekkürler ...

yönerge bağlantı işlevinde sahibim

app.directive('element',function($compile){
  .
  .
     var addXml = function(){
     var el = $compile('<xml-definitions definitions="definitions" />')($scope);
     $scope.renderingElement = el.html();
     }
  .
  .

ve yönerge şablonunda:

<span compile="renderingElement"></span>
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.