813 votes

Insérer du HTML dans la vue à partir du contrôleur AngularJS

Est-il possible de créer un HTML dans un contrôleur AngularJS et faire apparaître ce HTML dans la vue ?

Cela vient d'une exigence de transformer un blob JSON incohérent en une liste imbriquée de id: value paires. Par conséquent, le HTML est créé dans le contrôleur et je cherche maintenant à l'afficher.

J'ai créé une propriété de modèle, mais je ne parviens pas à la rendre dans la vue sans qu'elle n'imprime simplement l'adresse de l'utilisateur. HTML .


Mise à jour

Il semble que le problème vienne du fait qu'Angular rende le HTML créé sous la forme d'une chaîne entre guillemets. Je vais essayer de trouver un moyen de contourner ce problème.

Exemple de contrôleur :

var SomeController = function () {

    this.customHtml = '<ul><li>render me please</li></ul>';
}

Exemple de vue :

<div ng:bind="customHtml"></div>

Donne :

<div>
    "<ul><li>render me please</li></ul>"
</div>

1 votes

Veuillez également consulter cette question demandant s'il est possible d'exécuter des scripts dans le HTML inséré.

0 votes

Est-il possible d'avoir plusieurs objets liés au même ng-bind ? Comme par exemple : "ng-bind="site.address_1 site.address_2 site.zip".

0 votes

si vous avez beaucoup de choses sur votre page, vous devrez modifier la ligne 15046 de angular.js (insanity) de function htmlSanitizer(html) {... . Les développeurs d'Angular ont décidé que vous devriez être capable de trouver n'importe quelle liaison html en passant lentement par tous les éléments cachés de vos pages un par un pour trouver ce SEUL morceau de html manquant. ! !! très en colère contre une telle supposition ! !!

1135voto

Luke Madera Points 3187

Pour Angular 1.x, utilisez ng-bind-html dans le HTML :

<div ng-bind-html="thisCanBeusedInsideNgBindHtml"></div>

À ce stade, vous obtiendrez un attempting to use an unsafe value in a safe context Vous devez donc soit utiliser ngSanitize ou $sce pour résoudre ce problème.

$sce

Utilisez $sce.trustAsHtml() dans le contrôleur pour convertir la chaîne html.

 $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);

ngSanitize

Il y a deux étapes :

  1. inclure la ressource angular-sanitize.min.js, c'est-à-dire :

    <script src="lib/angular/angular-sanitize.min.js"></script>
  2. Dans un fichier js (contrôleur ou généralement app.js), inclure ngSanitize, c'est-à-dire :

    angular.module('myApp', ['myApp.filters', 'myApp.services', 
        'myApp.directives', 'ngSanitize'])

31 votes

Dans Angular 1.2, ng-bind-html-unsafe a été supprimée et les deux directives ont été combinées. Voir : github.com/angular/angular.js/blob/master/

60 votes

Sans utiliser ngSanitize, cela peut être fait maintenant en utilisant $sce . Injectez-le dans le contrôleur et faites passer le html par lui. $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar); Sinon, j'ai continué à obtenir attempting to use an unsafe value in a safe context

3 votes

Nous avons besoin d'un peu de nettoyage ici qui est la bonne façon rien ne semble fonctionner pour moi.

313voto

Katie Astrauskas Points 161

Vous pouvez également créer un filtre comme suit :

var app = angular.module("demoApp", ['ngResource']);

app.filter("trust", ['$sce', function($sce) {
  return function(htmlCode){
    return $sce.trustAsHtml(htmlCode);
  }
}]);

Puis dans la vue

<div ng-bind-html="trusted_html_variable | trust"></div>

Note : Ce filtre fait confiance à tout le html qui lui est passé, et pourrait présenter une vulnérabilité XSS si des variables avec des entrées utilisateur lui sont passées.

0 votes

@Katie Astrauskas, merci pour la réponse ! C'est très propre. BTW ngResource La dépendance n'est pas nécessaire.

28 votes

Ne l'utilisez que si vous faites entièrement confiance au HTML. Cette option n'assainit pas le HTML, mais permet seulement à Angular de l'injecter dans la page. Un HTML malveillant peut provoquer des attaques XSS.

0 votes

Si les performances sont importantes, vous devez éviter d'utiliser des filtres. Un filtre déclenchera deux digests à chaque fois.

122voto

MyName Points 530

Angular JS affiche le HTML à l'intérieur de la balise

La solution fournie dans le lien ci-dessus a fonctionné pour moi, aucune des options de ce fil n'a fonctionné. Pour tous ceux qui cherchent la même chose avec AngularJS version 1.2.9

Voici une copie :

Ok, j'ai trouvé une solution à ce problème :

JS :

$scope.renderHtml = function(html_code)
{
    return $sce.trustAsHtml(html_code);
};

HTML :

<p ng-bind-html="renderHtml(value.button)"></p>

EDIT :

Voici l'installation :

Fichier JS :

angular.module('MyModule').controller('MyController', ['$scope', '$http', '$sce',
    function ($scope, $http, $sce) {
        $scope.renderHtml = function (htmlCode) {
            return $sce.trustAsHtml(htmlCode);
        };

        $scope.body = '<div style="width:200px; height:200px; border:1px solid blue;"></div>'; 

    }]);

Fichier HTML :

<div ng-controller="MyController">
    <div ng-bind-html="renderHtml(body)"></div>
</div>

7 votes

Sachez que vous devez être absolument sûr que le html est digne de confiance. Sinon, la porte est grande ouverte aux attaques XSS.

0 votes

Cette solution, qui consiste à utiliser une fonction pour rendre le HTML, est la seule qui ait fonctionné pour moi.

0 votes

à quoi sert le "$http" ?

66voto

Pier-Luc Gendreau Points 2288

Heureusement, vous n'avez pas besoin de filtres sophistiqués ou de méthodes non sécurisées pour éviter ce message d'erreur. Il s'agit de l'implémentation complète permettant d'afficher correctement le balisage HTML dans une vue, de la manière prévue et sûre.

Le module sanitize doit être inclus après Angular :

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-sanitize.js"></script>

Ensuite, le module doit être chargé :

angular.module('app', [
  'ngSanitize'
]);

Cela vous permettra d'inclure des balises dans une chaîne de caractères à partir d'un contrôleur, d'une directive, etc :

scope.message = "<strong>42</strong> is the <em>answer</em>.";

Enfin, dans un modèle, il doit être édité comme suit :

<p ng-bind-html="message"></p>

Ce qui produira le résultat attendu : 42 est le réponse .

1 votes

Essayez un code html comme <div><label>Why My Input Element Missing</label><input /></div> ... Si cela vous surprend alors mettez à jour votre réponse plz... Parce que j'ai testé toutes les solutions 10+vote... Votre solution n'a pas fonctionné pour moi pour voir mes balises d'entrée ... bien autrement ... J'avais utilisé $sce.trustAsHtml(html)

0 votes

Cette solution fonctionne, vous pouvez poster un jsfiddle ou un plunkr ?

0 votes

Cela devrait être la réponse si vous utilisez la dernière version d'Angular.

62voto

Damax Points 549

J'ai essayé aujourd'hui, le seul moyen que j'ai trouvé est celui-ci

<div ng-bind-html-unsafe="expression"></div>

6 votes

Cette solution ne doit être utilisée que si la source est fiable afin d'éviter les attaques de type "cross-site scripting".

3 votes

Depuis la version 1.0.2 d'Angular, cela fonctionne pour moi, sans qu'aucun autre fichier ou connexion ne soit nécessaire.

1 votes

J'utilise Angular 1.0.8 et cela a fonctionné pour moi. Tenez compte de l'avertissement de @Bertrand cependant, assurez-vous de faire confiance à la source.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X