Wie man ng-bind-html dazu bringt, anglejs-Code zu kompilieren

Lesezeit: 8 Minuten

Ich arbeite mit anglejs 1.2.0-rc.3. Ich möchte HTML-Code dynamisch in eine Vorlage einfügen. Dafür verwende ich im Controller:

html = "<div>hello</div>";
$scope.unicTabContent = $sce.trustAsHtml(html);

In der Vorlage habe ich:

<div id="unicTab" ng-bind-html="unicTabContent"></div>

Es funktioniert gut für normalen HTML-Code. Aber wenn ich versuche, eine Winkelvorlage einzufügen, wird sie nicht interpretiert, sondern nur in die Seite eingefügt. Ich würde zum Beispiel gerne aufnehmen:

<div ng-controller="formCtrl">
    <div ng-repeat="item in content" ng-init="init()">
    </div>
</div>

Vielen Dank

  • Ja, das ist nicht gerade, wie eckig wirken will. Wenn Sie HTML dynamisch hinzufügen möchten, schauen Sie in die $complie Bedienung.

    – David Tryon

    1. November 2013 um 11:53 Uhr

  • Warum verwenden Sie nicht ngScript, um die About-Vorlage zu erstellen, und verwenden dann ein ng-include, ng-src, um sie hinzuzufügen

    – Vinod Ludwig

    1. November 2013 um 11:55 Uhr


Wie man ng bind html dazu bringt anglejs Code zu kompilieren
Ryan.lay

Diese Lösung verwendet keine hartcodierten Vorlagen, und Sie können Angular-Ausdrücke kompilieren, die in eine API-Antwort eingebettet sind.


Schritt 1.
Installieren Sie diese Direktive: https://github.com/incuna/angular-bind-html-compile

Schritt 2. Fügen Sie die Direktive in das Modul ein.

angular.module("app", ["angular-bind-html-compile"])

Schritt 3. Verwenden Sie die Direktive in der Vorlage:

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

Ergebnis:

Controller-Objekt

 $scope.letter = { user: { name: "John"}}

JSON-Antwort

{ "letterTemplate":[
    { content: "<span>Dear {{letter.user.name}},</span>" }
]}

HTML-Ausgabe =

<div bind-html-compile="letterTemplate.content"> 
   <span>Dear John,</span>
</div>

Zu Referenzzwecken hier die entsprechende Richtlinie:

(function () {
    'use strict';

    var module = angular.module('angular-bind-html-compile', []);

    module.directive('bindHtmlCompile', ['$compile', function ($compile) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                scope.$watch(function () {
                    return scope.$eval(attrs.bindHtmlCompile);
                }, function (value) {
                    element.html(value);
                    $compile(element.contents())(scope);
                });
            }
        };
    }]);
}());

  • Diese jsfiddle hilft, den Kompilierungsunterschied zwischen zu veranschaulichen ng-bind-html und bind-html-compile: jsfiddle.net/HB7LU/14557

    – Henry Blyth

    24. Juni 2015 um 17:38 Uhr

  • Ich glaube, ich habe diese Frage dreimal gestellt, bevor mir klar wurde, wie einfach dies mein Problem lösen würde. Ich würde es zweimal positiv bewerten, wenn ich könnte.

    – David

    1. April 2016 um 19:12 Uhr

Wie man ng bind html dazu bringt anglejs Code zu kompilieren
Haschbraun

Das ist, was ich gemacht habe, keine Ahnung, ob es das ist der eckige WegTMaber es funktioniert und ist super einfach;

.directive('dynamic', function($compile) {
    return {
        restrict: 'A',
        replace: true,
        link: function (scope, element, attrs) {
            scope.$watch(attrs.dynamic, function(html) {
                $compile(element.html(html).contents())(scope);
            });
        }
    };
});

Damit;

<div id="unicTab" dynamic="unicTabContent"></div>

Bearbeiten: Ich habe den eckigen Weg gefundenund sein Super einfach.

$templateCache.put('unicTabContent', $sce.trustAsHtml(html));
<div id="unicTab" ng-include="'unicTabContent'"></div>

Sie müssen keine eigenen Anweisungen oder ähnliches erstellen. Aber es ist eine einmal gebundene Art von Deal, Änderungen an Ihrem HTML-Code werden nicht angezeigt wie die benutzerdefinierte Direktive tut es.

  • Ich finde, diese Antwort ist am einfachsten zu implementieren.

    – entfernt

    23. November 2016 um 8:29 Uhr


  • Hey, warum verwendest du hier $watch? Warum nicht einfach das Element durch den kompilierten Inhalt ersetzen? danke btw.

    – ColacX

    17. Juli 2017 um 16:09 Uhr


  • Wenn sich also die Variable ändert, wird diese Änderung beim nächsten im DOM widergespiegelt digest. Wenn sich Ihre Variable nie ändern würde, können Sie dies natürlich vereinfachen, aber wann immer ich eine Antwort gebe, versuche ich, sie so allgemein und universell anwendbar wie möglich zu halten. Für meinen speziellen Fall denke ich, dass meine Variable leer war, als die Direktive ausgewertet wurde, also brauchte ich die watch für wann die Variable schließlich gefüllt wird.

    – Haschbraun

    18. Juli 2017 um 2:31 Uhr

  • Das hat bei mir viel besser funktioniert! Besonders wenn Sie auch einen Filter mit dem Element verwenden, ist dies definitiv der richtige Weg. Ich bekomme ein Digest-Limit erreicht, wenn ich die Sache angle-bind -html-compile verwende

    – Nasarij

    9. Oktober 2017 um 21:25 Uhr

  • Irgendwie kann ich das ng-html-compile bedingt machen? Ich meine, die Direktive nur unter einer bestimmten Bedingung anhängen / zuweisen, z. B. – Rasterzeile anklicken und sich sonst normal verhalten?

    – RedBottleSanitizer

    22. Oktober 2021 um 17:08 Uhr

Wie Vinod Louis in seinem Kommentar sagt, war der beste Weg, dies zu tun, die Verwendung von Vorlagen. Ich musste eine Vorlage außerhalb des regulären Codes definieren, zum Beispiel habe ich diesen Code in meine index.html eingefügt:

<script type="text/ng-template" id="unic_tab_template.html">
    <div ng-switch on="page">
        <div ng-switch-when="home"><p>{{home}}</p></div>
        <div ng-switch-when="form">
            <div ng-controller="formCtrl">
                <div ng-repeat="item in content">{{item.name}}:{{item.value}}</div>
            </div>
        </div>
        <div ng-switch-default>an error accured</div>
    </div>
</script>

Diese Vorlage ist bedingt, sodass je nach Wert von $scope.page zwischen den 3 Vorlagen gewechselt wird (die dritte ist ein Fehlerbehandler). Um es zu benutzen hatte ich:

<div id="unicTab" ng-controller="unicTabCtrl">
    <div ng-include="'unic_tab_template.html'"></div>
</div>

Auf diese Weise ändert sich meine Seite abhängig vom $Scope in meinem unicTabCtrl-Controller.

Zusammenfassend lässt sich sagen, dass die Idee, Angularsjs-Vorlagen einzufügen, schwierig zu realisieren ist ($compile scheint die Lösung zu sein, aber ich konnte es nicht zum Laufen bringen). Stattdessen können Sie bedingte Vorlagen verwenden.

  • Ich mag diese Lösung, aber es wäre besser gewesen, wenn wir ein Beispiel sehen könnten, woher das HTML von woanders kommt (z. B. Remote-JSON und daher nicht fest im Projekt codiert).

    – Wouter

    4. Mai 2014 um 7:46 Uhr

Ich habe versucht, dasselbe zu tun, und bin auf dieses Modul gestoßen.

http://ngmodules.org/modules/ng-html-compile

Ich habe es einfach eingefügt und konnte dann “ng-html-compile” anstelle von “ng-bind-html” verwenden.

Eine Möglichkeit besteht darin, eine Direktive zu verwenden, um benutzerdefinierte Vorlagen einzufügen, die Winkelausdrücke enthalten

<div id="unicTab" unic-tab-content></div>
app.directive("unicTabContent",function(){
   return {
      restrict:"A",
      template:'{{unicTabContent}}'
   }
})

  • Ich mag diese Idee, und sie enthält den Code, aber sie ist immer noch nicht kompiliert.

    – Clemens Roblot

    1. November 2013 um 13:22 Uhr

  • funktioniert hier so wie es ist plnkr.co/edit/sUOxHBUYIdQlAiM3Dy0V?p=Vorschau Vielleicht haben Sie einige verschachtelte Anweisungen oder etwas anderes, was dazu führt, dass es nicht funktioniert

    – charlietfl

    1. November 2013 um 16:51 Uhr


  • Aber ich möchte, dass es den Code in der Variablen kompiliert, die Sie Test genannt haben. Zum Beispiel Plunker die

    und

    anzeigen, was ich nicht möchte.

    – Clemens Roblot

    1. November 2013 um 17:20 Uhr


  • OK..kann es mit machen link Rückruf der Direktive Plunker

    – charlietfl

    1. November 2013 um 17:28 Uhr


  • Es kompiliert zwar html, aber nicht die eckigen Aussagen. Im Plunker Wenn die Testvariable direkt injiziert wird, ist die ng-click-Methode verbunden, aber wenn sie mit der Direktive injiziert wird, ist dies nicht der Fall.

    – Clemens Roblot

    1. November 2013 um 17:43 Uhr


1645905913 682 Wie man ng bind html dazu bringt anglejs Code zu kompilieren
Lukas Frankowski

Meine Lösung für ein ähnliches Problem in meiner aktuellen App ohne Verwendung einer Vorlage (nicht elegant, aber funktionierend):

directive('ngBindHtmlCompile', ['$compile', function ($compile) {
    return {
        restrict: 'A',
        compile: function compile(tElement, tAttributes, transcludeFn) {
            return function postLink(scope, element, attributes) {
                scope.$watch(function() {
                    return scope.$eval(attributes.ngBindHtml);
                }, function(newValue, oldValue) {
                    $compile(element.children())(scope);
                });
            };
        }
    };
}]);

Es benötigt ngBindHtml auf demselben Element und kompiliert den Elementinhalt, nachdem er sich mit geändert hat ngBindHtml.

<div id="unicTab" ng-bind-html="unicTabContent" ng-bind-html-compile></div>

ng-html-compile sieht ähnlich aus, wird aber auf den ersten Blick nicht neu berechnet, wenn sich der Vorlageninhalt ändert. Aber ich habe es nicht probiert.

  • Ich mag diese Idee, und sie enthält den Code, aber sie ist immer noch nicht kompiliert.

    – Clemens Roblot

    1. November 2013 um 13:22 Uhr

  • funktioniert hier so wie es ist plnkr.co/edit/sUOxHBUYIdQlAiM3Dy0V?p=Vorschau Vielleicht haben Sie einige verschachtelte Anweisungen oder etwas anderes, was dazu führt, dass es nicht funktioniert

    – charlietfl

    1. November 2013 um 16:51 Uhr


  • Aber ich möchte, dass es den Code in der Variablen kompiliert, die Sie Test genannt haben. Zum Beispiel Plunker die

    und

    anzeigen, was ich nicht möchte.

    – Clemens Roblot

    1. November 2013 um 17:20 Uhr


  • OK..kann es mit machen link Rückruf der Direktive Plunker

    – charlietfl

    1. November 2013 um 17:28 Uhr


  • Es kompiliert zwar html, aber nicht die eckigen Aussagen. Im Plunker Wenn die Testvariable direkt injiziert wird, ist die ng-click-Methode verbunden, aber wenn sie mit der Direktive injiziert wird, ist dies nicht der Fall.

    – Clemens Roblot

    1. November 2013 um 17:43 Uhr


1641817791 604 Was bedeutet x Pakete suchen nach Finanzierung wenn npm install
Stokely

Der folgende Code ist viel einfacher, wenn die in Angular integrierten $interpolate- und $sce-Objekte verwendet werden. Fügen Sie zuerst die Objekte $interpolate und $sce Angular in Ihre Direktive ein, während Sie alles tun, was Sie in Ihrer Direktive benötigen.

amqApp.directive('myDir', ['$interpolate', '$sce', function ($interpolate,$sce ) {...}

Then create all your scoped variables found in your imported html expressions…

$scope.custom = 'Hello World';

Next use $interpolate to process your custom HTML and its expressions…then make sure you use the $sce object to trust it as HTML before binding…

var html = $interpolate('<b>{{custom}}</b>')($scope);    
$scope.data = $sce.trustAsHtml(html);

Finally, in your view, just make sure use an element with the “ng-bind” or “ng-bind-html” on it in your view display. I found the $sce piece wont display the HTML as HTML (sees it as text) if you don’t bind it in your html template like this…

<span ng-bind-html="data"></span>

You should see in bold…

Hello World

I used this trick to import in text/HTML with custom angular {{expressions}} from a web.config.

867710cookie-checkWie man ng-bind-html dazu bringt, anglejs-Code zu kompilieren

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy