Preservar saltos de línea en angularjs

176

He visto esta pregunta SO.

Mi código en lugar de ng-bind="item.desc"usos {{item.desc}}porque tengo un ng-repeatantes.

Entonces mi código:

<div ng-repeat="item in items">
  {{item.description}}
</div>

La descripción del artículo contiene \nlíneas nuevas que no se representan.

¿Cómo puede {{item.description}}mostrar las nuevas líneas fácilmente suponiendo que tengo lo ng-repeatanterior?

Diolor
fuente
¿Ponerlo en una etiqueta <pre>?
aet
88
Al peinar el envoltorio divcon style="white-space:pre-wrap;".
Stewie
1
El comentario de @Stewie funciona perfectamente para mí (AngularJS 1.2.18), muestra explícitamente cómo diseñar el elemento individual (a diferencia de la solución de pilau y Paul Weber) y no es necesario cambiar los estilos de la etiqueta <pre> como otros propuesto.
Andre Holzner
Tienes razón, supuse que todos saben cómo usar CSS básico y aplicar una clase a un elemento. Si Stewie hubiera publicado su comentario como respuesta, hubiera sido mejor para él. Aunque parece que tiene suficientes puntos ...
Paul Weber
Estoy de acuerdo, @Stewie definitivamente debería haber formateado su comentario como respuesta. Solucionó mi problema perfectamente.
CF_HoneyBadger

Respuestas:

285

Basado en la respuesta de @pilau, pero con una mejora que incluso la respuesta aceptada no tiene.

<div class="angular-with-newlines" ng-repeat="item in items">
   {{item.description}}
</div>

/* in the css file or in a style block */
.angular-with-newlines {
    white-space: pre-wrap;
}

Esto usará nuevas líneas y espacios en blanco como se indica, pero también dividirá el contenido en los límites del contenido. Puede encontrar más información sobre la propiedad de espacios en blanco aquí:

https://developer.mozilla.org/en-US/docs/Web/CSS/white-space

Si desea romper en las nuevas líneas, pero también colapsar múltiples espacios o espacios en blanco anteriores al texto (muy similar al comportamiento original del navegador), puede usar, como sugirió @aaki:

white-space: pre-line;

Buena comparación de los diferentes modos de representación: http://meyerweb.com/eric/css/tests/white-space.html

Paul Weber
fuente
1
La mejor solución aquí es IMO, ya que no cambia el estilo a una fuente monoespaciada como pre.
Troels Larsen
1
Mire el espacio en blanco que precede al texto, que se conservará.
Silver Paladin
1
¿Ya que lo mencionaste no sería pre-lineel preferido? Está más cerca de la forma en que HTML generalmente representa el contenido de texto de sus nodos y aún conserva las nuevas líneas.
aaki
Hmm ... tienes razón, la pre-línea es la mejor solución, después de que ya no estoy seguro de por qué elijo pre-wrap en lugar de pre-line. ¿Quizás el soporte del navegador para la línea previa no es tan bueno? Pero agregaré
Paul Weber
¡Esta debería ser la respuesta aceptada! pre-lineEs el camino a seguir. Gracias paul!
retiro el
126

Tratar:

<div ng-repeat="item in items">
  <pre>{{item.description}}</pre>
</div>

El <pre>contenedor imprimirá el texto \ncomo texto.

también si imprime el json, para una mejor apariencia use el jsonfiltro, como:

<div ng-repeat="item in items">
  <pre>{{item.description|json}}</pre>
</div>

Demo

Estoy de acuerdo con @Paul Weberque white-space: pre-wrap;es un mejor enfoque, de todos modos, el uso <pre>rápido, principalmente para depurar algunas cosas (si no desea perder tiempo en el estilo)

Maxim Shoustin
fuente
El item.description es texto que tiene las \náreas que no conozco, no al final. Creo que necesito el prebasado en tu edición.
Diolor
29
Muchas veces, una etiqueta <pre> no es una buena solución, ya que transforma el texto en mensajería y rompe el estilo de la página. El estilo = "espacio en blanco: pre-wrap;" la solución parece ser una mejor solución (al menos para mi situación)
CF_HoneyBadger
1
@CF_HoneyBadger bien, porque @pilaula respuesta de ustedes es correcta, pero no significa que la mía esté equivocada y, por lo tanto, me
votaron negativamente
Intenté convertir todo \na <br/>'s y luego, por supuesto, estas etiquetas no se representaron como marcado HTML ... después de toda esta conversión encontró su stylesolución y esta es una ayuda y simplificación increíbles ... ahora no tengo que seguir convirtiendo todos mis datos de backend y solo hacer algunos cambios en la Vista ... ¡Te mereces +1000!
twknab
Esto funciona para el código, pero no para mostrar mensajes a los usuarios, por ejemplo. Creo que la respuesta de Paul es la correcta
Quintonn
63

Es muy simple con CSS (funciona, lo juro).

.angular-with-newlines {
  white-space: pre;
}
  • Mira ma! ¡Sin etiquetas HTML adicionales!
pilau
fuente
@pilau Quiero ajustar el texto si contiene una coma (,) no espacios en blanco, ¿cómo puedo hacer esto?
Shylendra Madda
@shylendra mi solución no ajusta el texto, hace que se comporte como si estuviera en una preetiqueta. ¿Quizás abrir otra pregunta? ¿O tal vez me perdí tu punto?
pilau
Me preguntaba sobre la compatibilidad del navegador. De acuerdo con este gráfico, parece funcionar en todos los principales navegadores. Es mucho menos complicado que reemplazar las nuevas líneas con etiquetas br. ¡Gracias! Solo preste atención a formatear el código para que no contenga espacios, aparecerán, por supuesto. developer.mozilla.org/en-US/docs/Web/CSS/white-space
Paul Weber
Podría ser aún mejor usar espacios en blanco: preenvolver, de lo contrario el contenido nunca se ajustará.
Paul Weber
16

Con CSS esto se puede lograr fácilmente.

<div ng-repeat="item in items">
<span style="white-space:pre-wrap;"> {{item.description}}</span>
</div>  

O se puede crear una clase CSS para este propósito y se puede usar desde un archivo CSS externo

Rehan
fuente
2

Bueno, depende, si desea vincular datos, no debería haber ningún formato, de lo contrario, puede bind-htmly no description.replace(/\\n/g, '<br>') está seguro de que sea lo que desea.

Nicolas Brugneaux
fuente
1

la solución css funciona, sin embargo, realmente no tienes control sobre el estilo. En mi caso, quería un poco más de espacio después del salto de línea. Aquí hay una directiva que creé para manejar esto (mecanografiado):

function preDirective(): angular.IDirective {
    return {
        restrict: 'C',
        priority: 450,
        link: (scope, el, attr, ctrl) => {
            scope.$watch(
                () => el[0].innerHTML,
                (newVal) => {
                    let lineBreakIndex = newVal.indexOf('\n');
                    if (lineBreakIndex > -1 && lineBreakIndex !== newVal.length - 1 && newVal.substr(lineBreakIndex + 1, 4) != '</p>') {
                        let newHtml = `<p>${replaceAll(el[0].innerHTML, '\n\n', '\n').split('\n').join('</p><p>')}</p>`;
                        el[0].innerHTML = newHtml;
                    }
                }
            )
        }
    };

    function replaceAll(str, find, replace) {
        return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
    }

    function escapeRegExp(str) {
        return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
    }
}

angular.module('app').directive('pre', preDirective);

Utilizar:

<div class="pre">{{item.description}}</div>

Todo lo que hace es envolver cada parte del texto en una <p>etiqueta. Después de eso, puedes diseñarlo como quieras.

Dmitry Efimenko
fuente
1

Solo agrega esto a tus estilos, esto funciona para mí

white-space: pre-wrap

Por este texto <textarea>se puede mostrar como está allí con espacios y frenos de línea

HTML

   <p class="text-style">{{product?.description}}</p>

CSS

.text-style{
    white-space: pre-wrap
}
Akitha_MJ
fuente
0

Solo usa el estilo css "espacio en blanco: pre-wrap" y estarás listo. He tenido el mismo problema en el que necesito manejar mensajes de error para los cuales los saltos de línea y los espacios en blanco son realmente particulares. ¡Acabo de agregar este en línea donde estaba vinculando los datos y funciona como Charm!

Siddhartha Thota
fuente
0

Tuve un problema similar para ti. No estoy tan interesado en las otras respuestas aquí porque realmente no le permiten diseñar el comportamiento de la nueva línea con mucha facilidad. No estoy seguro si tiene control sobre los datos originales, pero la solución que adopté fue cambiar los "elementos" de ser una matriz de cadenas a ser una matriz de matrices, donde cada elemento en la segunda matriz contenía una línea de texto . De esa manera puedes hacer algo como:

<div ng-repeat="item in items">
  <p ng-repeat="para in item.description">
     {{para}}
  </p>
</div>

De esta manera, puede aplicar clases a los párrafos y aplicarles un estilo agradable con CSS.

Chris Rae
fuente