it-swarm.com.de

Angular HTML-Bindung

Ich schreibe eine Angular -Anwendung und habe eine HTML-Antwort, die ich anzeigen möchte.

Wie mache ich das? Wenn ich einfach die Bindungssyntax {{myVal}} verwende, codiert sie (natürlich) alle HTML-Zeichen.

Ich muss irgendwie das innerHTML eines div an den Variablenwert binden.

704
Aviad P.

Die korrekte Syntax lautet wie folgt:

<div [innerHTML]="theHtmlString"></div>

Funktioniert mit 8.1.2

Dokumentationsreferenz

1146
prolink007

Angular 2.0.0 und Angular 4.0.0 final

Nur für sichere Inhalte

<div [innerHTML]="myVal"></div>

DOMSanitizer

Potenziell unsicheres HTML muss mithilfe des Angulars DOM-Bereinigungsprogramms explizit als vertrauenswürdig gekennzeichnet werden, damit potenziell unsichere Teile des Inhalts nicht entfernt werden

<div [innerHTML]="myVal | safeHtml"></div>

mit einer Pfeife mögen

@Pipe({name: 'safeHtml'})
export class Safe {
  constructor(private sanitizer:DomSanitizer){}

  transform(style) {
    return this.sanitizer.bypassSecurityTrustHtml(style);
    //return this.sanitizer.bypassSecurityTrustStyle(style);
    // return this.sanitizer.bypassSecurityTrustXxx(style); - see docs
  }
}

Siehe auch In RC.1 können einige Stile nicht mit Bindungssyntax hinzugefügt werden

Und docs: https://angular.io/api/platform-browser/DomSanitizer

Sicherheitswarnung

Das Vertrauen in vom Benutzer hinzugefügtes HTML kann ein Sicherheitsrisiko darstellen. Die vor genannten Dokumente Zustand:

Durch Aufrufen einer der bypassSecurityTrust... -APIs wird Angulars integrierte Bereinigung für den übergebenen Wert deaktiviert. Überprüfen und überwachen Sie sorgfältig alle Werte und Codepfade, die in diesen Aufruf einfließen. Stellen Sie sicher, dass Benutzerdaten für diesen Sicherheitskontext entsprechend geschützt sind. Weitere Informationen finden Sie im Sicherheitshandbuch .

Angular Markup

So etwas wie

class FooComponent {
  bar = 'bar';
  foo = `<div>{{bar}}</div>
    <my-comp></my-comp>
    <input [(ngModel)]="bar">`;

mit

<div [innerHTML]="foo"></div>

bewirkt nicht, dass Angular irgendetwas Angular-spezifisches in foo verarbeitet. Angular ersetzt Angular spezifisches Markup zur Erstellungszeit durch generierten Code. Zur Laufzeit hinzugefügtes Markup wird von Angular nicht verarbeitet.

Um HTML-Code mit Angular-spezifischem Markup (Eigenschafts- oder Wertebindung, Komponenten, Anweisungen, Pipes usw.) hinzuzufügen, müssen Sie das dynamische Modul hinzufügen und Komponenten zur Laufzeit kompilieren. Diese Antwort enthält weitere Details Wie kann ich eine dynamische Vorlage verwenden/erstellen, um eine dynamische Komponente mit Angular 2.0 zu kompilieren?

275

[innerHtml] ist in den meisten Fällen eine großartige Option, schlägt jedoch bei sehr großen Zeichenfolgen fehl oder wenn Sie eine fest codierte Formatierung in HTML benötigen.

Ich würde gerne einen anderen Ansatz teilen:

Alles, was Sie tun müssen, ist, ein div in Ihrer HTML-Datei zu erstellen und ihm eine ID zu geben:

<div #dataContainer></div>

Erstellen Sie dann in Ihrer Angular 2-Komponente einen Verweis auf dieses Objekt (TypeScript hier):

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
    templateUrl: "some html file"
})
export class MainPageComponent {

    @ViewChild('dataContainer') dataContainer: ElementRef;

    loadData(data) {
        this.dataContainer.nativeElement.innerHTML = data;
    }
}

Verwenden Sie dann einfach die Funktion loadData, um Text an das HTML-Element anzuhängen.

Es ist nur ein Weg, wie Sie es mit nativem Javascript machen würden, aber in einer Angular Umgebung. Ich empfehle es nicht, weil Code unordentlicher wird, aber manchmal gibt es keine andere Option.

Siehe auch Angular 2 - innerHTML-Stil

160
Piotrek

Bei [email protected]:

Html-Binding funktioniert nicht, wenn ein {{interpolation}} verwendet wird. Verwenden Sie stattdessen einen "Ausdruck":

ungültig

<p [innerHTML]="{{item.anleser}}"></p>

-> wirft einen Fehler (Interpolation statt erwarteten Ausdruck)

richtig

<p [innerHTML]="item.anleser"></p>

-> das ist der richtige weg.

sie können dem Ausdruck weitere Elemente hinzufügen, z.

<p [innerHTML]="'<b>'+item.anleser+'</b>'"></p>

Hinweis

HTML, das mit [innerHTML] hinzugefügt wurde (oder dynamisch mit anderen Mitteln wie element.appenChild() oder ähnlichem hinzugefügt wurde), wird von Angular in keiner Weise verarbeitet, außer aus Sicherheitsgründen.
Solche Dinge funktionieren nur, wenn der HTML-Code statisch zu einer Komponentenvorlage hinzugefügt wird. Wenn Sie dies benötigen, können Sie zur Laufzeit eine Komponente erstellen, wie in Wie kann ich eine dynamische Vorlage verwenden/erstellen, um eine dynamische Komponente mit Angular 2.0 zu kompilieren?

45
jvoigt

Die direkte Verwendung von [innerHTML] ohne Verwendung des DOM-Desinfektionsprogramms von Angular ist keine Option, wenn es vom Benutzer erstellte Inhalte enthält. Die von @ GünterZöchbauer vorgeschlagene safeHtml-Pipe in seiner Antwort ist eine Möglichkeit, den Inhalt zu bereinigen. Die folgende Anweisung ist eine andere:

import { Directive, ElementRef, Input, OnChanges, Sanitizer, SecurityContext,
  SimpleChanges } from '@angular/core';

// Sets the element's innerHTML to a sanitized version of [safeHtml]
@Directive({ selector: '[safeHtml]' })
export class HtmlDirective implements OnChanges {
  @Input() safeHtml: string;

  constructor(private elementRef: ElementRef, private sanitizer: Sanitizer) {}

  ngOnChanges(changes: SimpleChanges): any {
    if ('safeHtml' in changes) {
      this.elementRef.nativeElement.innerHTML =
        this.sanitizer.sanitize(SecurityContext.HTML, this.safeHtml);
    }
  }
}

Benutzt werden

<div [safeHtml]="myVal"></div>
23
Rene Hamburger

Das funktioniert bei mir: <div innerHTML = "{{ myVal }}"></div> (Angular2, Alpha 33)

Gemäß einem anderen SO: Einfügen von HTML vom Server in DOM mit angle2 (allgemeine DOM-Manipulation in Angular2 entspricht "inner-html" "ng-bind-html" in Angular 1.X

19
Fan Li

Um eine vollständige Antwort zu erhalten, können Sie auch Folgendes verwenden, wenn sich Ihr HTML-Inhalt in einer Komponentenvariablen befindet:

<div [innerHTML]=componementVariableThatHasTheHtml></div>
11
Serj Sagan

Ich entschuldige mich, wenn ich den Punkt hier verpasse, aber ich möchte einen anderen Ansatz empfehlen:

Ich denke, es ist besser, Rohdaten von Ihrer serverseitigen Anwendung zurückzugeben und sie auf der Clientseite an eine Vorlage zu binden. Dies sorgt für schnellere Anfragen, da Sie nur json von Ihrem Server zurücksenden.

Für mich scheint es nicht sinnvoll, Angular zu verwenden, wenn Sie nur HTML vom Server abrufen und es "wie es ist" in das DOM einfügen.

Ich weiß, dass Angular 1.x eine HTML-Bindung hat, aber ich habe noch kein Gegenstück in Angular 2.0 gesehen. Sie könnten es aber später hinzufügen. Wie auch immer, ich würde immer noch eine Daten-API für Ihre Angular 2.0-App in Betracht ziehen.

Ich habe hier ein paar Beispiele mit einigen einfachen Datenbindungen, wenn Sie interessiert sind: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples

9
TGH

Verwenden Sie einfach das [innerHTML] -Attribut in Ihrem HTML.

<div [innerHTML]="myVal"></div>

Hatten Sie jemals Eigenschaften in Ihrer Komponente, die HTML-Markups oder Entitäten enthalten, die Sie in Ihrer Vorlage anzeigen müssen? Die traditionelle Interpolation wird nicht funktionieren, aber die Bindung der innerHTML-Eigenschaften hilft.

Die Verwendung von {{myVal}}NICHT funktioniert wie erwartet! Dies wird nicht nimm die HTML-Tags wie <p>, <strong> usw. auf und übergebe sie nur als Zeichenketten ...

Stellen Sie sich vor, Sie haben diesen Code in Ihrer Komponente:

const myVal:string ='<strong>Stackoverflow</strong> is <em>helpful!</em>'

Wenn Sie {{myVal}} verwenden, wird dies in der Ansicht angezeigt:

<strong>Stackoverflow</strong> is <em>helpful!</em>

mit [innerHTML]="myVal" wird das Ergebnis jedoch wie folgt erwartet:

Stackoverflow ist hilfreich!

4
Alireza

Wir können HTML-Inhalt immer an die Eigenschaft innerHTML übergeben, um dynamischen HTML-Inhalt wiederzugeben. Dieser dynamische HTML-Inhalt kann jedoch auch infiziert oder bösartig sein. Bevor wir also dynamischen Inhalt an innerHTML übergeben, sollten wir immer sicherstellen, dass der Inhalt bereinigt ist (mithilfe von DOMSanitizer), damit wir allen schädlichen Inhalten entgehen können.

Versuchen Sie unter Rohr:

import { Pipe, PipeTransform } from "@angular/core";
import { DomSanitizer } from "@angular/platform-browser";

@Pipe({name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform {
    constructor(private sanitized: DomSanitizer) {
    }
    transform(value: string) {
        return this.sanitized.bypassSecurityTrustHtml(value);
    }
}

Usage:
<div [innerHTML]="content | safeHtml"></div>
1
Suneet Bansal

In Angular 2 können Sie 3 Arten von Bindungen ausführen:

  • [property]="expression" -> Jede HTML-Eigenschaft kann mit einer verknüpfen
    Ausdruck. In diesem Fall wird die Eigenschaft "Ausdrucksänderungen" aktualisiert, dies funktioniert jedoch nicht in der anderen Richtung.
  • (event)="expression" -> Wenn das Ereignis aktiviert wird, führen Sie den Ausdruck aus.
  • [(ngModel)]="property" -> Bindet die Eigenschaft von js (oder ts) an html. Alle Aktualisierungen dieser Eigenschaft sind überall sichtbar.

Ein Ausdruck kann ein Wert, ein Attribut oder eine Methode sein. Zum Beispiel: '4', 'controller.var', 'getValue ()'

Beispiel hier

1
adrisons

Arbeiten in AngularJS v2.1.1

<div [innerHTML]="variable or htmlString">
</div>
0
FACode

Wenn Sie dies in Angular 2 oder Angular 4 möchten und auch Inline-CSS beibehalten möchten, können Sie verwenden

<div [innerHTML]="theHtmlString | keepHtml"></div>
0
Jay Momaya

Wie in Angular 2 erläutert, können Elemente dynamisch zu DOM hinzugefügt werden, indem die ViewContainerRef-Klasse von @ Angular/core verwendet wird.

Sie müssen lediglich eine Direktive deklarieren, die ViewContainerRef implementiert und sich wie ein Platzhalter in Ihrem DOM verhält.

Richtlinie

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appInject]'
})
export class InjectDirective {

  constructor(public viewContainerRef: ViewContainerRef) { }

}

Dann gehen Sie in der Vorlage, in die Sie die Komponente einfügen möchten, wie folgt vor:

HTML

<div class="where_you_want_to_inject">    
  <ng-template appInject></ng-template>
</div>

Anschließend fügen Sie aus dem eingefügten Komponentencode die Komponente ein, die den gewünschten HTML-Code enthält:

import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { InjectDirective } from '../inject.directive';
import { InjectedComponent } from '../injected/injected.component';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

  @ViewChild(InjectDirective) injectComp: InjectDirective;

  constructor(private _componentFactoryResolver: ComponentFactoryResolver) {
  }

  ngOnInit() {
  }

  public addComp() {
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(InjectedComponent);
    const viewContainerRef = this.injectComp.viewContainerRef;
    const componentRef = viewContainerRef.createComponent(componentFactory);
  }

  public removeComp() {
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(InjectedComponent);
    const viewContainerRef = this.injectComp.viewContainerRef;
    const componentRef = viewContainerRef.remove();
  }

}

Ich habe eine voll funktionsfähige Demo-App auf Angular 2 fügt der DOM-Demo dynamisch eine Komponente hinz

0
BogdanC

Sie können diese Methode verwenden

<div [innerHTML]=var></div>

oder binde es durch id

 <div #html></div>

und in der Komponente

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
    templateUrl: "some html file"
})
export class MainPageComponent {

    @ViewChild('dataContainer') dataContainer: ElementRef;

    loadData(data) {
        this.dataContainer.nativeElement.innerHTML = data;
    }
}
0

Sie können verschiedene Ansätze verwenden, um die Lösung zu erzielen. Wie bereits in der genehmigten Antwort erwähnt, können Sie Folgendes verwenden:

<div [innerHTML]="myVal"></div>

je nachdem, was Sie erreichen möchten, können Sie auch andere Dinge wie Javascript DOM ausprobieren (nicht empfohlen, DOM-Operationen sind langsam):

Präsentation

<div id="test"></test>

Komponente

var p = document.getElementsById("test");
p.outerHTML = myVal;

Eigenschaftsbindung

Javascript DOM Outer HTML

0
João Beirão