Reliure angulaire en HTML

j'écris une application angulaire et j'ai une réponse HTML que je veux afficher.

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

je dois d'une façon ou d'une autre lier le html interne d'un div à la valeur variable.

504
demandé sur Narendra Jadhav 2015-07-21 22:48:39

15 réponses

La syntaxe correcte est maintenant la suivante:

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

6.1.9

Référence De La Documentation

877
répondu prolink007 2018-10-03 19:11:20

Angulaire 2.0.0 et Angulaire 4.0.0 finale

Pour la sécurité du contenu

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

DOMSanitizer

le code HTML potentiellement dangereux doit être explicitement identifié comme fiable en utilisant Angulars DOM sanitizer afin de ne pas rayer les parties potentiellement dangereuses du contenu

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

avec un tuyau 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 en utilisant la syntaxe de reliure

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

avertissement de Sécurité

confiance utilisateur HTML ajouté peut poser un risque de sécurité. L'avant mentionnés docs état:

appelant l'un des bypassSecurityTrust... APIs désactive la désinfection intégrée D'Angular pour la valeur transmise. Vérifiez et auditez soigneusement toutes les valeurs et les chemins de code entrant dans cet appel. Assurez-vous que toutes les données de l'utilisateur sont correctement échappées pour ce contexte de sécurité. Pour plus de détails, voir le Guide de sécurité .

marque 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 provoquera pas Angular à traiter quoi que ce soit de spécifique à L'angle dans foo . Angular remplace Angular specific markup at build time par du code généré. La marge ajoutée à l'exécution ne sera pas traitée par angulaire .

pour ajouter HTML qui contient un markup spécifique à un angle (fixation de propriété ou de valeur, composants, directives, pipes, ...) il est nécessaire d'ajouter le module dynamique et de compiler les composants à l'exécution. Ce réponse fournit plus de détails Comment puis-je utiliser/créer un modèle dynamique pour la compilation dynamique de la Composante Angulaire 2.0?

188
répondu Günter Zöchbauer 2018-02-07 09:52:04

[innerHtml] est une excellente option dans la plupart des cas, mais elle échoue avec de très grandes chaînes ou lorsque vous avez besoin de style codé en html.

je voudrais partager une autre approche:

Tout ce que vous devez faire, est de créer un div dans votre fichier html et donner quelques id:

<div #dataContainer></div>

alors, dans votre composant angulaire 2, Créer une référence à cet objet (dactylographié 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;
    }
}

alors il suffit d'utiliser loadData fonction pour ajouter du texte à l'élément html.

c'est juste une façon de le faire en utilisant le javascript natif, mais dans un environnement angulaire. Je ne le recommande pas, car il rend le code plus confus, mais parfois il n'y a pas d'autre option.

Voir aussi Angulaire 2 - innerHTML style

124
répondu Piotrek 2017-07-19 08:17:16

sur angular2@2.0.0-alpha.44:

Html-de la Liaison ne fonctionnera pas lors de l'utilisation d'un {{interpolation}} , une "Expression" au lieu de:

invalide

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

- > envoie une erreur (Interpolation au lieu de l'Expression attendue)

correct

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

- > c'est la bonne voie.

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

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

indice

HTML ajouté en utilisant [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 sauf la désinfection pour la sécurité.

De telles choses ne fonctionnent que lorsque le HTML est ajouté statiquement à un modèle de components. Si vous avez besoin de cela, vous pouvez créer un composant à l'exécution comme expliqué dans Comment puis-je utiliser / créer dynamic template pour compiler dynamic Component avec Angular 2.0?

25
répondu jvoigt 2017-08-23 14:18:29

ça marche pour moi: <div innerHTML = "{{ myVal }}"></div> (Angular2, Alpha 33)

selon un autre SO: insérant le HTML du serveur dans le DOM avec angular2 (manipulation générale du DOM en Angular2) ," inner-html "est équivalent à" ng-bind-html " en Angular 1.X

14
répondu Fan Li 2017-05-23 11:55:01

utilisant [innerHTML] directement sans utiliser le désinfectant DOM D'Angular n'est pas une option si elle contient du contenu créé par l'utilisateur. La pipe safeHtml suggérée par @GünterZöchbauer dans sa réponse est une façon d'assainir 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>
14
répondu Rene Hamburger 2017-05-23 12:10:46

juste pour faire pour une réponse complète, si votre contenu html est dans une variable de Composant, vous pouvez également utiliser:

<div [innerHTML]=componementVariableThatHasTheHtml></div>
9
répondu Serj Sagan 2015-12-31 05:43:42

Je m'excuse si je passe à côté de l'essentiel, mais je voudrais recommander une approche différente:

je pense qu'il est préférable de retourner 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 retournez que json depuis votre serveur.

pour moi, il ne semble pas logique d'utiliser Angular si tout ce que vous faites est de récupérer du html à partir du serveur et de l'injecter "tel quel" dans le DOM.

je connais Angular 1.x a une liaison html, mais je n'ai pas encore vu de contrepartie dans Angular 2.0. Ils pourraient 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 échantillons ici avec quelques données de liaison simple si vous êtes intéressé: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples

7
répondu TGH 2015-07-21 22:17:44

utilisez simplement [innerHTML] dans votre attribut HTML , quelque chose comme ceci ci-dessous:

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

a déjà eu des propriétés dans votre composant qui contiennent un markup html ou les entités que vous avez besoin dans votre modèle? Le traditionnel interpolation ne fonctionnera pas, mais la liaison de propriété innerHTML vient à sauvetage.

par {{myVal}} fonctionne comme prévu! Ce ne va pas récupérer les balises HTML comme <p> , <strong> etc et passer que comme des chaînes...

Imaginez que vous ayez ce code dans votre component:

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

Si vous utilisez {{myVal}} , vous obtiendrez cette vision:

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

mais en utilisant [innerHTML]="myVal" fait le résultat attendu comme ceci:

Stackoverflow est utile!

1
répondu Alireza 2017-10-10 12:31:06

travaillant à AngularJS v2.1.1

<div [innerHTML]="variable or htmlString">
</div>
0
répondu FACode 2016-11-23 07:05:31

la façon d'ajouter dynamiquement des éléments à DOM, comme expliqué sur L'Angular 2 doc, est en utilisant la classe ViewContainerRef de @Angular/core.

ce que vous devez faire est de déclarer une directive qui mettra en œuvre ViewContainerRef et agir comme un placeholder sur votre DOM.

Directive

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

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

  constructor(public viewContainerRef: ViewContainerRef) { }

}

Puis, 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 injecterez le composant contenant le HTML que vous voulez:

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 ajouter dynamiquement un composant à la démo DOM

0
répondu BogdanC 2017-06-29 13:02:15

si vous avez des gabarits dans votre application angulaire (ou n'importe quel framework), et que vous renvoyez des gabarits HTML de votre backend via une requête/réponse HTTP, vous mélangez des gabarits entre le frontend et le backend.

pourquoi ne pas simplement laisser le matériel de templage soit dans le frontend (je suggère que), ou dans le backend (assez intransparent imo)?

et si vous gardez des gabarits dans la fronde, pourquoi ne pas simplement répondre avec JSON pour les demandes à l'arrière-plan. Vous n'avez même pas à mettre en place une structure RESTful, mais garder les gabarits d'un côté rend votre code plus transparent.

cela va payer en retour quand quelqu'un d'autre doit faire face à votre code (ou même vous êtes vous-même entrer votre propre code après un certain temps)!

si vous le faites correctement, vous aurez de petits composants avec de petits gabarits, et le meilleur de tous, si votre code est imba, quelqu'un qui ne connaît pas les langues de codage sera être en mesure de comprendre vos modèles et votre logique! Donc en plus, gardez vos fonctions / méthodes aussi petites que vous le pouvez. Vous découvrirez par la suite que le maintien, le remaniement, la révision et l'ajout de fonctionnalités seront beaucoup plus faciles à comparer à de grandes fonctions/méthodes/classes et à mélanger le templage et la logique entre le frontend et le backend - et garder autant de logique dans le backend si votre frontend a besoin d'être plus flexible (par exemple en écrivant un frontend android ou en passant à un autre frontend cadre).

de la Philosophie, de l'homme :)

p. S.: vous n'avez pas à mettre en œuvre le code 100% clean, car il est très coûteux - surtout si vous devez motiver les membres de l'équipe ;) mais: vous devriez trouver un bon équilibre entre une approche de code plus propre et ce que vous avez (peut-être qu'il est déjà assez propre)

vérifiez le livre si vous le pouvez et laissez-le entrer dans votre âme: https://de.wikipedia.org/wiki/Clean_Code

0
répondu Guntram 2017-08-30 23:40:47

dans angulaire 2 vous pouvez faire 3 types de reliures:

  • [property]="expression" -> toute propriété html peut créer un lien vers une

    expression. Dans ce cas, si l'expression change, la propriété sera mise à jour., mais cela ne fonctionne pas dans l'autre sens.
  • (event)="expression" - > quand l'événement active l'expression d'exécution.
  • [(ngModel)]="property" -> Lie la propriété de js (ou ts) au format html. Toute mise à jour sur cette propriété sera perceptible partout.

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

exemple ici

-1
répondu adrisons 2017-05-23 12:26:36

le code ci-dessous vous aidera

myval vous pouvez remplacer par le html désiré

<div [innerHTML]="myVal"></div>
-1
répondu Rahul Cv 2017-07-06 10:16:05

essayez ce code

votre chaîne avec la balise html comme ci-dessous

htmlString:string = "Hello<br/>Html"

vous pouvez obtenir la chaîne de caractères dans la page html

<ion-content>
<ion-item>
<div [innerHTML] = "'<p>' + htmlString + '</p>'"></div>
</ion-item>
</ion-content>
-2
répondu Finava Vipul 2017-04-04 12:50:40