web-dev-qa-db-fra.com

Insérer HTML dans la vue

Est-il possible de créer un fragment HTML dans un contrôleur AngularJS et d'afficher ce code HTML dans la vue?

Cela vient de la nécessité de transformer un blob JSON incohérent en une liste imbriquée de paires id : value. Par conséquent, le code 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 peux pas la restituer dans la vue sans imprimer le code HTML.


Mettre à jour

Il semble que le problème provienne du rendu angulaire du code HTML créé sous forme de chaîne entre guillemets. Je vais essayer de trouver un moyen de contourner cela.

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>
767
Swaff

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

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

À ce stade, vous obtiendrez une erreur attempting to use an unsafe value in a safe context, vous devez donc 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 2 étapes:

  1. inclure la ressource angular-sanitize.min.js, à savoir:
    <script src="lib/angular/angular-sanitize.min.js"></script>

  2. Dans un fichier js (contrôleur ou généralement app.js), incluez ngSanitize, c'est-à-dire:
    angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngSanitize'])

1102
Luke Madera

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

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>

Remarque : Ce filtre approuve tout code HTML qui lui est transmis et peut présenter une vulnérabilité XSS si des variables avec une entrée utilisateur lui sont transmises.

304
Katie Astrauskas

JS angulaire affiche le code HTML dans 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 recherchent la même chose avec AngularJS version 1.2.9

Voici une copie: 

Ok j'ai trouvé une solution pour ça:

JS:

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

HTML:

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

MODIFIER:

Voici la mise en place:

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>
116
anpatel

Heureusement, vous n'avez pas besoin de filtres sophistiqués ni de méthodes dangereuses pour éviter ce message d'erreur. Ceci est l'implémentation complète pour produire correctement le balisage HTML dans une vue de la manière prévue et sûre.

Le module de désinfection 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 du balisage dans une chaîne 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 sorti comme suit:

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

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

63
Pier-Luc Gendreau

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

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

61
Damax

ng-bind-html-unsafe ne fonctionne plus. 

C'est le moyen le plus court:

Créer un filtre:

myApp.filter('unsafe', function($sce) { return $sce.trustAsHtml; });

Et à votre avis:

<div ng-bind-html="customHtml | unsafe"></div>

P.S. Cette méthode ne vous oblige pas à inclure le module ngSanitize.

51
Bidhan Bhattarai

sur html

<div ng-controller="myAppController as myCtrl">

<div ng-bind-html-unsafe="myCtrl.comment.msg"></div>

OR

<div ng-bind-html="myCtrl.comment.msg"></div

sur le contrôleur

mySceApp.controller("myAppController", function myAppController( $sce) {

this.myCtrl.comment.msg = $sce.trustAsHtml(html);

fonctionne aussi avec $scope.comment.msg = $sce.trustAsHtml(html);

25
Sotos

Depuis Angular 4, voici comment cela fonctionne:

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

Tiré de cette question ici.

16
Garth

J'ai trouvé que l'utilisation de ng-sanitize ne me permettait pas d'ajouter ng-click dans le code HTML.

Pour résoudre ce problème, j'ai ajouté une directive. Comme ça:

app.directive('htmldiv', function($compile, $parse) {
return {
  restrict: 'E',
  link: function(scope, element, attr) {
    scope.$watch(attr.content, function() {
      element.html($parse(attr.content)(scope));
      $compile(element.contents())(scope);
    }, true);
  }
}
});

Et voici le code HTML:

<htmldiv content="theContent"></htmldiv>

Bonne chance.

9
Matt

Je viens de faire cela en utilisant ngBindHtml en suivant angular (v1.4) docs ,

<div ng-bind-html="expression"></div> 
and expression can be "<ul><li>render me please</li></ul>"

Assurez-vous d'inclure ngSanitize dans les dépendances du module . Cela devrait alors fonctionner correctement.

6
Henry Neo

Une autre solution, très similaire à blrbr's, à l'exception de l'utilisation d'un attribut scoped, est

angular.module('app')
.directive('renderHtml', ['$compile', function ($compile) {
    return {
      restrict: 'E',
      scope: {
        html: '='
      },
      link: function postLink(scope, element, attrs) {

          function appendHtml() {
              if(scope.html) {
                  var newElement = angular.element(scope.html);
                  $compile(newElement)(scope);
                  element.append(newElement);
              }
          }

          scope.$watch(function() { return scope.html }, appendHtml);
      }
    };
  }]);

Et alors 

<render-html html="htmlAsString"></render-html>

Notez que vous pouvez remplacer element.append() par element.replaceWith()

4
jmb-mage

il existe une solution supplémentaire à ce problème en créant un nouvel attribut ou des directives dans angular.

product-specs.html 

 <h4>Specs</h4>
        <ul class="list-unstyled">
          <li>
            <strong>Shine</strong>
            : {{product.shine}}</li>
          <li>
            <strong>Faces</strong>
            : {{product.faces}}</li>
          <li>
            <strong>Rarity</strong>
            : {{product.rarity}}</li>
          <li>
            <strong>Color</strong>
            : {{product.color}}</li>
        </ul>

app.js

 (function() {
var app = angular.module('gemStore', []);    
app.directive("     <div ng-show="tab.isSet(2)" product-specs>", function() {
return {
  restrict: 'E',
  templateUrl: "product-specs.html"
};
});

index.html

 <div>
 <product-specs>  </product-specs>//it will load product-specs.html file here.
 </div>

ou 

<div  product-specs>//it will add product-specs.html file 

ou 

<div ng-include="product-description.html"></div>

https://docs.angularjs.org/guide/directive

3
yugi

vous pouvez également utiliserng-include

<div class="col-sm-9 TabContent_container" ng-include="template/custom.html">
</div>

vous pouvez utiliser"ng-show"pour afficher masquer ces données de modèle.

3
Vikash Sharma

Utilisation

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

et

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

Pour cela, vous devez inclure angular-sanitize.js, Par exemple dans votre fichier html avec

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-sanitize.js"></script>
1
Patricia Beier

voici la solution faire un filtre comme celui-ci 

.filter('trusted',
   function($sce) {
     return function(ss) {
       return $sce.trustAsHtml(ss)
     };
   }
)

et appliquer cela comme un filtre à la ng-bind-html comme

<div ng-bind-html="code | trusted">

et merci à Ruben Decrop

1
bahri noredine

Simplement utiliser [innerHTML], comme ci-dessous:

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

Avant de devoir utiliser ng-bind-html...

0
Alireza

Voici une directive simple (et dangereuse) bind-as-html, sans nécessité de ngSanitize:

myModule.directive('bindAsHtml', function () {
    return {
        link: function (scope, element, attributes) {
            element.html(scope.$eval(attributes.bindAsHtml));
        }
    };
});

Notez que cela s'ouvrira pour des problèmes de sécurité, si vous liez un contenu non fiable.

Utilisez comme si:

<div bind-as-html="someHtmlInScope"></div>
0
user3638471