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>
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.
Utilisez $sce.trustAsHtml()
dans le contrôleur pour convertir la chaîne HTML.
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);
Il y a 2 étapes:
inclure la ressource angular-sanitize.min.js, à savoir:<script src="lib/angular/angular-sanitize.min.js"></script>
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'])
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.
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>
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.
J'ai essayé aujourd'hui, le seul moyen que j'ai trouvé était celui-ci
<div ng-bind-html-unsafe="expression"></div>
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
.
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);
Depuis Angular 4, voici comment cela fonctionne:
<div [innerHTML]="htmlString">
</div>
Tiré de cette question ici.
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.
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.
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()
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>
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.
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>
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
Simplement utiliser [innerHTML]
, comme ci-dessous:
<div [innerHTML]="htmlString"></div>
Avant de devoir utiliser ng-bind-html
...
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>