Estoy tratando de convertir caracteres de nueva línea ( \n
) a html br
.
Según esta discusión en el Grupo de Google , esto es lo que tengo:
myApp.filter('newlines', function () {
return function(text) {
return text.replace(/\n/g, '<br/>');
}
});
La discusión allí también aconseja utilizar lo siguiente en la vista:
{{ dataFromModel | newline | html }}
Esto parece estar usando el html
filtro antiguo , mientras que ahora se supone que debemos usar el ng-bind-html
atributo.
Independientemente, esto plantea un problema: no quiero que ningún HTML de la cadena original ( dataFromModel
) se represente como HTML; solo los br
's.
Por ejemplo, dada la siguiente cadena:
Mientras que 7> 5
todavía no quiero HTML y otras cosas aquí ...
Me gustaría que saliera:
While 7 > 5<br>I still don't want html & stuff in here...
¿Hay alguna forma de lograr esto?
fuente
pre-line
es probablemente mejor en general, ya que las filas largas se ajustarán (como lo haría con cualquier<br>
solución basada).pre-wrap
parece ser lo que la mayoría de la gente quiere (no pre-line): "El navegador conserva los espaciosEn lugar de jugar con nuevas directivas, decidí usar solo 2 filtros:
App.filter('newlines', function () { return function(text) { return text.replace(/\n/g, '<br/>'); } }) .filter('noHTML', function () { return function(text) { return text .replace(/&/g, '&') .replace(/>/g, '>') .replace(/</g, '<'); } });
Luego, en mi opinión, canalizo uno en el otro:
<span ng-bind-html-unsafe="dataFromModel | noHTML | newlines"></span>
fuente
text.replace(/\\n/g, '<br />')
o incluso mejortext.replace(/(\\r)?\\n/g, '<br />')
Una forma más sencilla de hacer esto es hacer un filtro que divida el texto en cada uno
\n
en una lista, y luego usar `ng-repeat.El filtro:
App.filter('newlines', function() { return function(text) { return text.split(/\n/g); }; });
y en el html:
<span ng-repeat="line in (text | newlines) track by $index"> <p> {{line}}</p> <br> </span>
fuente
<p ng-repeat="line in (line.message | newlines)">{{line}}</p>
track by
en el caso de las líneas duplicadas, lo que plantearía un error:line in (text | newlines) track by $index
.Si no desea destruir el diseño con cadenas infinitas, use pre-line:
<p style="white-space: pre-line;">{{ MyMultiLineText}}</p>
fuente
No sé si Angular tiene un servicio para eliminar html, pero parece que necesita eliminar html antes de pasar su
newlines
filtro personalizado. La forma en que lo haría es a través de unano-html
directiva personalizada , a la que se le pasaría una propiedad de alcance y el nombre de un filtro para aplicar después de eliminar elhtml
<div no-html="data" post-filter="newlines"></div>
Aquí está la implementación
app.directive('noHtml', function($filter){ return function(scope, element, attrs){ var html = scope[attrs.noHtml]; var text = angular.element("<div>").html(html).text(); // post filter var filter = attrs.postFilter; var result = $filter(filter)(text); // apending html element.html(result); }; });
Lo importante es la
text
variable. Aquí creo un elemento DOM intermedio y le agrego el HTML usando elhtml
método y luego recupero solo el texto con eltext
método. Ambos métodos son proporcionados por la versión lite de jQuery de Angular .La siguiente parte es la aplicación del
newline
filtro, que se realiza mediante el$filter
servicio.Compruebe el plunker aquí: http://plnkr.co/edit/SEtHH5eUgFEtC92Czq7T?p=preview
fuente
Una actualización del filtro con ng-bind-html actualmente sería:
myApp.filter('newlines', function () { return function(text) { return text.replace(/( )? /g, '<br/>'); } });
y el filtro noHTML ya no es necesario.
La solución de espacios en blanco tiene poca compatibilidad con el navegador: http://caniuse.com/#search=tab-size
fuente
Un poco tarde para la fiesta en esto, pero sugeriría una pequeña mejora para verificar cadenas nulas / indefinidas.
Algo como:
.filter('newlines', function () { return function(text) { return (text) ? text.replace(/( )? /g, '<br/>') : text; }; })
O (un poco más apretado)
.filter('newlines', function () { return function(text) { return (text instanceof String || typeof text === "string") ? text.replace(/( )? /g, '<br/>') : text; }; })
fuente