Pregunta

¿Es posible crear un fragmento HTML en un controlador AngularJS y hacer este HTML en la vista?

Esto proviene de un requisito de convertir una mancha de JSON inconsistente en una lista anidada de id : value pares. Por lo tanto, el HTML se crea en el controlador y ahora estoy buscando mostrarlo.

He creado una propiedad modelo, pero no puedo rendir esto en la vista sin que solo imprima el HTML.


Actualizar

Parece que el problema surge de la representación angular del html creado como una cadena dentro de las citas. Intentará encontrar una forma de evitar esto.

Controlador de ejemplo:

var SomeController = function () {

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

Vista de ejemplo:

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

Da :

<div>
    "<ul><li>render me please</li></ul>"
</div>
¿Fue útil?

Solución

Para Angular 1.x, usa ng-bind-html En el HTML:

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

En este punto obtendrías un attempting to use an unsafe value in a safe context error para que necesite usar ngsanitizar o $ SCE Para resolver eso.

$ SCE

Usar $sce.trustAsHtml() en el controlador para convertir la cadena HTML.

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

ngsanitizar

Hay 2 pasos:

  1. Incluya el recurso Angular Sanitize.min.js, es decir:
    <script src="lib/angular/angular-sanitize.min.js"></script>

  2. En un archivo js (controlador o generalmente app.js), incluya ngsanitize, es decir:
    angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngSanitize'])

Otros consejos

También puede crear un filtro como así:

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

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

Entonces en la vista

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

Nota: Este filtro confía en todos y cada uno de los HTML que se le pasan y podría presentar una vulnerabilidad de XSS si las variables con la entrada del usuario se pasan a él.

Angular JS muestra HTML dentro de la etiqueta

La solución proporcionada en el enlace anterior funcionó para mí, ninguna de las opciones en este hilo lo hizo. Para cualquiera que busque lo mismo con AngularJS versión 1.2.9

Aquí hay una copia:

Ok, encontré una solución para esto:

JS:

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

HTML:

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

EDITAR:

Aquí está la configuración:

Archivo 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>'; 

    }]);

Archivo HTML:

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

Afortunadamente, no necesita filtros elegantes o métodos inseguros para evitar ese mensaje de error. Esta es la implementación completa para obtener correctamente el marcado HTML en una vista de la manera prevista y segura.

El módulo de desinfectación debe incluirse después de 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>

Luego, el módulo debe cargarse:

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

Esto le permitirá incluir el marcado en una cadena de un controlador, directiva, etc.:

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

Finalmente, en una plantilla, debe ser salida como así:

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

Que producirá la salida esperada: 42 es el responder.

Lo he intentado hoy, la única forma en que encontré fue esta

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

ng-bind-html-unsafe ya no funciona.

Esta es la forma más corta:

Crear un filtro:

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

Y en tu opinión:

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

Ps Este método no requiere que incluya el ngSanitize módulo.

en html

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

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

O

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

en controlador

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

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

funciona también con $scope.comment.msg = $sce.trustAsHtml(html);

Descubrí que usar Ng-Sanitize no me permitía agregar Ng-Click en el HTML.

Para resolver esto, agregué una directiva. Como esto:

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

Y este es el HTML:

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

Buena suerte.

Acabo de hacer esto usando ngbindhtml siguiendo Docios angulares (V1.4),

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

Asegúrese de incluir ngsanitizar en las dependencias del módulo. Entonces debería funcionar bien.

Otra solución, muy similar a la de BLRBR, excepto que usa un atributo de alcance es:

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

Y entonces

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

Nota que puede reemplazar element.append() con element.replaceWith()

Hay una solución más para este problema utilizando la creación de nuevos atributo o directivas en angular.

Producto-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>

o

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

o

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

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

también puedes usar ng-include.

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

puedes usar "ng-show" Para mostrar ocultar estos datos de plantilla.

Usar

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

y

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

Para eso, debes incluir angular-sanitize.js, por ejemplo en su archivo HTML con

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

Aquí está la solución, haga un filtro como este

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

y aplique esto como un filtro al ng-bind-html como

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

Y gracias a Ruben Decrop

Aquí hay un simple (e inseguro) bind-as-html directiva, sin la necesidad de ngSanitize:

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

Tenga en cuenta que esto se abrirá para problemas de seguridad, si es vinculante contenido no confiable.

Úselo así:

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

Ejemplo de trabajo con tubería para mostrar HTML en plantilla con Angular 4.

1. Escape de tubería con reducción-html.pipe.ts

`

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({name : 'keepHtml', pure : false})
export class EscapeHtmlPipe implements PipeTransform{
 constructor(private sanitizer : DomSanitizer){
 }
 transform(content){
  return this.sanitizer.bypassSecurityTrustHtml(content);
 }
}

`2. Registre la tubería en App.module.ts

 import {EscapeHtmlPipe} from './components/pipes/escape-html.pipe';
    declarations: [...,EscapeHtmlPipe]
  1. Usar en su plantilla

        <div class="demoPipe"  [innerHtml]="getDivHtml(obj.header) | keepHtml">

  2. getDivHtml() { //can return html as per requirement}

    Agregue la implementación adecuada para GetDivhtml en el archivo de componentes asociados.

Simplemente uso [innerHTML], como abajo:

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

Antes de que necesitaras usar ng-bind-html...

En Angular 7 + Ionic 4, los contenidos HTML se pueden mostrar usando [InnerHTML]:

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

Espero que esto también te ayude. Gracias.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top