web-dev-qa-db-fra.com

Angular Liaison HTML

J'écris une application Angular et je souhaite afficher une réponse HTML.

Comment je fais ça? Si j'utilise simplement la syntaxe de liaison {{myVal}}, elle code tous les caractères HTML (bien sûr).

J'ai besoin d'une certaine manière de lier la innerHTML d'un div à la valeur de la variable.

704
Aviad P.

La syntaxe correcte est la suivante:

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

Fonctionne sur 8.1.2

Référence de la documentation

1146
prolink007

angulaire 2.0.0 et Angular 4.0.0 final

Pour un contenu sûr juste

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

DOMSanitizer

Le code HTML potentiellement dangereux doit être explicitement identifié comme approuvé en utilisant le désinfectant DOM Angulars afin de ne pas supprimer les parties du contenu potentiellement dangereuses.

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

avec une pipe comme

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

Voir aussi Dans RC.1, certains styles ne peuvent pas être ajoutés à l'aide de la syntaxe de liaison

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

Avertissement de sécurité

Faire confiance au HTML ajouté par l’utilisateur peut poser un risque de sécurité. L'avant documentation mentionnée déclare:

L'appel de l'une des API bypassSecurityTrust... désactive le nettoyage intégré d'Angular pour la valeur transmise. Vérifiez et auditez minutieusement toutes les valeurs et chemins de code entrant dans cet appel. Assurez-vous que toutes les données utilisateur sont correctement protégées pour ce contexte de sécurité. Pour plus de détails, voir le Guide de sécurité .

Balisage angulaire

Quelque chose comme

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

avec

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

ne fera en sorte que Angular ne traite rien de ce qui est spécifique à Angular dans foo. Angular remplace le balisage spécifique Angular au moment de la compilation avec le code généré. Les annotations ajoutées au moment de l'exécution ne seront pas traitées par Angular .

Pour ajouter du HTML contenant un balisage spécifique à Angular (liaison de propriété ou de valeur, composants, directives, tubes, ...), il est nécessaire d'ajouter le module dynamique et de compiler les composants au moment de l'exécution. Cette réponse fournit plus de détails Comment utiliser/créer un modèle dynamique pour compiler un composant dynamique avec Angular 2.0?

275
Günter Zöchbauer

[innerHtml] est une excellente option dans la plupart des cas, mais il échoue avec des chaînes très volumineuses ou lorsque vous avez besoin d'un style codé en dur en HTML.

Je voudrais partager une autre approche:

Tout ce que vous avez à faire est de créer une div dans votre fichier html et de lui donner un identifiant:

<div #dataContainer></div>

Ensuite, dans votre composant Angular 2, créez une référence à cet objet (TypeScript ici):

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

Ensuite, utilisez simplement la fonction loadData pour ajouter du texte à un élément HTML.

C'est juste une façon de le faire en utilisant du javascript natif, mais dans un environnement Angular. Je ne le recommande pas, car le code est plus compliqué, mais parfois, il n'y a pas d'autre option.

Voir aussi Angular 2 - innerHTML styling

160
Piotrek

Sur [email protected]:

Html-Binding ne fonctionnera pas si vous utilisez un {{interpolation}}, utilisez plutôt une "expression":

invalide

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

-> émet une erreur (interpolation au lieu de l'expression attendue)

correct

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

-> c'est la bonne façon.

vous pouvez ajouter des éléments supplémentaires à l'expression, comme:

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

Indice

Le HTML ajouté à l'aide de [innerHTML] (ou ajouté dynamiquement par d'autres moyens, comme element.appenChild() ou similaire) ne sera pas traité par Angular de quelque manière que ce soit, à l'exception de la désinfection pour des raisons de sécurité.
Cela ne fonctionne que lorsque le code HTML est ajouté de manière statique à un modèle de composants. Si vous en avez besoin, vous pouvez créer un composant au moment de l'exécution, comme expliqué dans la section Comment utiliser/créer un modèle dynamique pour compiler un composant dynamique avec Angular 2.0?

45
jvoigt

Utiliser directement [innerHTML] sans utiliser l'assainisseur DOM d'Angular n'est pas une option s'il contient du contenu créé par l'utilisateur. Le tuyau safeHtml proposé par @ GünterZöchbauer dans sa réponse est un moyen de désinfecter le contenu. La directive suivante en est une autre:

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

À utiliser

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

Cela fonctionne pour moi: <div innerHTML = "{{ myVal }}"></div> (Angular2, Alpha 33)

Selon un autre SO: insertion du code HTML du serveur dans le DOM avec angular2 (manipulation générale du DOM dans Angular2) , "inner-html" est équivalent à "ng-bind-html" dans Angular 1 FOIS

19
Fan Li

Juste pour obtenir une réponse complète, si votre contenu HTML est dans une variable de composant, vous pouvez également utiliser:

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

Je m'excuse si je manque le point ici, mais je voudrais recommander une approche différente:

Je pense qu'il est préférable de renvoyer les données brutes de votre application côté serveur et de les lier à un modèle du côté client. Cela rend les requêtes plus agiles puisque vous ne renvoyez que JSON depuis votre serveur.

Pour moi, il ne semble pas logique d'utiliser Angular si vous ne faites qu'extraire du code HTML du serveur et l'injecter "tel quel" dans le DOM.

Je sais que Angular 1.x a une liaison HTML, mais je n'ai pas encore vu de contrepartie dans Angular 2.0. Ils pourraient cependant l'ajouter plus tard. Quoi qu'il en soit, je considérerais toujours une API de données pour votre application Angular 2.0.

J'ai quelques exemples ici avec une simple liaison de données si vous êtes intéressé: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples

9
TGH

Il vous suffit simplement d’utiliser l’attribut [innerHTML] dans votre HTML, un peu comme ceci ci-dessous:

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

Vous avez déjà eu des propriétés dans votre composant contenant du balisage HTML ou des entités que vous devez afficher dans votre modèle? L'interpolation traditionnelle ne fonctionnera pas, mais la liaison de la propriété innerHTML vient à la rescousse.

Utiliser {{myVal}}NE PAS fonctionne comme prévu! Ceci ne le fera pas récupère les balises HTML telles que <p>, <strong> etc et le transmet uniquement sous forme de chaînes ...

Imaginez que vous avez ce code dans votre composant:

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

Si vous utilisez {{myVal}}, vous obtiendrez ceci dans la vue:

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

mais en utilisant [innerHTML]="myVal", le résultat attendu est le suivant:

Stackoverflow est utile!

4
Alireza

Nous pouvons toujours transmettre le contenu html à la propriété innerHTML pour afficher le contenu dynamique html, mais ce contenu html dynamique peut également être infecté ou malveillant. Par conséquent, avant de passer du contenu dynamique à innerHTML, nous devons toujours nous assurer que le contenu est désinfecté (à l'aide de DOMSanitizer) afin de pouvoir échapper à tout contenu malveillant.

Essayez ci-dessous pipe:

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

Dans Angular 2 , vous pouvez créer 3 types de liaisons:

  • [property]="expression" -> Toute propriété HTML peut être liée à un
    expression. Dans ce cas, si la propriété expression changes est mise à jour, mais cela ne fonctionne pas dans l'autre sens.
  • (event)="expression" -> When event active l'expression d'exécution.
  • [(ngModel)]="property" -> Lie la propriété de js (ou ts) à html. Toute mise à jour sur cette propriété sera visible partout.

Une expression peut être une valeur, un attribut ou une méthode. Par exemple: '4', 'controller.var', 'getValue ()'

Exemple ici

1
adrisons

Travailler dans AngularJS v2.1.1

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

Si vous voulez que dans Angular 2 ou Angular 4 et que vous souhaitiez également conserver le CSS en ligne, vous pouvez utiliser

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

La manière d'ajouter dynamiquement des éléments au DOM, comme expliqué à la documentation Angular 2, consiste à utiliser la classe ViewContainerRef de @ Angular/core.

Ce que vous devez faire est de déclarer une directive qui implémentera ViewContainerRef et agira comme un espace réservé sur votre DOM.

Directive

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

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

  constructor(public viewContainerRef: ViewContainerRef) { }

}

Ensuite, dans le modèle où vous voulez injecter le composant:

HTML

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

Ensuite, à partir du code de composant injecté, vous allez injecter le composant contenant le code HTML souhaité:

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

}

J'ai ajouté une application de démonstration entièrement fonctionnelle sur Angular 2 ajoute dynamiquement un composant à la démo DOM

0
BogdanC

Vous pouvez utiliser cette méthode

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

ou le lier par id

 <div #html></div>

et dans la composante

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

Vous pouvez utiliser plusieurs approches pour atteindre la solution. Comme déjà dit dans la réponse approuvée, vous pouvez utiliser:

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

en fonction de vos objectifs, vous pouvez également essayer d'autres méthodes, telles que DOM javascript (déconseillé, les opérations DOM sont lentes):

Présentation

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

Composant

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

Liaison de propriété

Javascript DOM Outer HTML

0
João Beirão