javascript - print - ng-bind-html angularjs not working
Escapando &> caracteres en ng-bind en AngularJs (6)
¿Por qué no usar simplemente $ sce.trustAsHtml?
Tengo un caso de uso, donde podemos tener los caracteres ''&'' y ''>'' en una cadena. p.ej. Johnson & Johnson, value > 3
. Entonces, mientras la respuesta del servidor está codificada, el valor se convierte en ''value & gt; 3 ''.
ng-bind
no admite lo siguiente:
value > 3
value > 3
se representará para ngBind
, mientras que el navegador muestra el mismo contenido que value > 3
.
Ng:bind <div ng-bind="model"></div>
Ng:bind-html <div ng-bind-html="model"></div>
<div> From Div: value > </div>
¿Por qué este comportamiento predeterminado del navegador no está presente en ng-bind
? No quiero usar ng-bind-html
(tiene problemas con el valor <
y no es un html) o ng-bind-unsafe-html
.
Mi aplicación tiene campos de valor clave dinámicos que se mostrarán en diferentes partes de la aplicación. Por lo tanto, se requerirá una sobrecarga adicional para usar una directiva o decorador por separado para mostrar todos los campos de cadena que para usar ngBind
.
Preguntas:
1) ¿Hay alguna otra manera de hacer lo mismo sin usar una directiva adicional, o es esta la manera correcta de manejar los datos codificados?
2) ¿Puedo anular el comportamiento de ng-bind
o decorarlo por defecto?
Esto es HTML:
>
Puede que no tenga etiquetas HTML, pero sigue siendo HTML. Si desea utilizar ng-bind
, su servidor debe devolver texto no codificado. Es decir, >
lugar de >
.
Use ng-bind-html
o modifique su servidor para devolver texto sin formato sin que html lo codifique primero.
Edición: demostración rápida que ilustra el uso de >
y >
en JavaScript:
div1.innerHTML = ">"; // write HTML
div2.textContent = ">"; // write plain text
console.log(div1.innerHTML === div2.innerHTML);
console.log(div1.textContent === div2.textContent);
Recuerdo una directiva llamada ngBindHtmlUnsafe disponible para tales casos de uso.
http://code.angularjs.org/1.0.8/docs/api/ng.directive:ngBindHtmlUnsafe
Por favor refiérase a esto. No estoy seguro si esto está disponible en versiones posteriores inestables. Este es un enlace a la última versión estable disponible.
Sí, vamos a "decorarlo" con un filtro:
.filter("decode",function(){
return function(str){
var el = document.createElement("div");
el.innerHTML = str;
str = el.textContent || el.innerText;
return str;
}
});
Y úselo como: <div ng-bind="model|decode"></div>
Ejemplo de trabajo: http://jsfiddle.net/HKahG/5/
Inspirado en esta respuesta: https://.com/a/784698/1206613
ng-bind usa el método .text () para reemplazar el texto y mientras su código contiene >
que es un marcado HTML, no se procesa correctamente mediante ng-bind. Debería usar ng-bind-html en este lugar ya que en realidad está ingresando contenido HTML. De lo contrario, puede reemplazar> por expresiones regulares a ''>''.
ej .: - model = model.replace(/>/g, ''>'');
Pero en este caso, debe reemplazar todos los marcadores HTML que no son necesarios ya que ng-bind-html ya está funcionando bien en su caso.
EDITAR : por favor, vaya directamente al final de la respuesta para obtener la mejor versión; la respuesta está en orden cronológico; Obtuve el código óptimo después de unas pocas iteraciones, al final. Gracias.
- ¿Puedo anular el comportamiento de ng-bind o decorarlo por defecto?
Sí. He hecho una implementación muy simple que hace que ng-bind
comporte como quieras. Bueno ... no estoy seguro de si esto es exactamente lo que quieres, pero al menos hace lo que entendí que quieres.
Fiddle de trabajo: http://jsfiddle.net/93QQM/
Y aquí está el código:
module.directive(''ngBind'', function() {
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind = ''myBind('' + tAttrs.ngBind + '')'';
return {
pre: function(scope) {
scope.myBind = function(text) {
return angular.element(''<div>'' + text + ''</div>'').text();
}
}
};
}
}
});
Esto no es exactamente una "directiva adicional", esta es la manera de "anular el comportamiento de ng-bind". No agrega una nueva directiva, solo extiende el comportamiento de la directiva ngBind existente.
En la función de compilación , modificamos el valor del atributo ng-bind
, envolviéndolo en una llamada de función. Con esto, tenemos acceso al valor original del modelo y la oportunidad de devolverlo modificado.
La función está disponible a través del alcance en la fase de vinculación previa, porque si lo hacemos en la fase posterior a la vinculación, la función estará disponible solo después de que la directiva ngBind original haya recuperado el valor del atributo (que será un cadena vacía, porque la función no será encontrada).
La función myBind
es simple e inteligente: crea un elemento, y el texto se usa, sin cambios, como cuerpo del elemento, solo para ser recuperado inmediatamente a través de la función de text
, que devolverá el contenido tal como "el navegador lo procesa".
De esta manera, puede usar ngBind como de costumbre, como <div ng-bind="model.content" />
, pero tiene este comportamiento modificado.
Versión mejorada
En lugar de adjuntar la función myBind
a todos los ámbitos donde se aplica ngBind, en cada fase de $rootScope
, podemos adjuntarla solo una vez al $rootScope
, haciéndolo disponible de inmediato para todos los ámbitos.
Nuevo violín de trabajo: http://jsfiddle.net/EUqP9/
Nuevo código:
module.directive(''ngBind'', [''$rootScope'', function($rootScope) {
$rootScope.myBind = function(text) {
return angular.element(''<div>'' + text + ''</div>'').text();
};
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind = ''myBind('' + tAttrs.ngBind + '')'';
}
};
}]);
Mucho más limpio que la versión anterior! Por supuesto, puede cambiar el nombre de la función myBind
a cualquier otro nombre que desee. El "costo" de la función es el siguiente: agregue esta función simple al ámbito raíz: usted decide si vale la pena el precio.
Otra versión más
Influido por la respuesta de Chemiv ... ¿por qué no elimina la función de cualquier ámbito y, en cambio, la convierte en un filtro? También funciona.
Otro nuevo problema de trabajo: http://jsfiddle.net/hQJaZ/
Y el nuevo código:
module.filter(''decode'', function() {
return function(text) {
return angular.element(''<div>'' + text + ''</div>'').text();
};
}).directive(''ngBind'', function() {
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind += ''|decode'';
}
};
});
Ahora tienes tres opciones para elegir del menú.