Preservar quebras de linha em angularjs

176

Eu já vi essa pergunta.

Meu código em vez de ng-bind="item.desc"usa {{item.desc}}porque eu tenho um ng-repeatantes.

Então meu código:

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

A descrição do item contém \npara novas linhas que não são renderizadas.

Como a {{item.description}}exibição das novas linhas pode facilmente assumir que eu tenho o ng-repeatdescrito acima?

Diolor
fonte
Colocá-lo em uma tag <pre>?
aet 30/10/2013
88
Ao estilizar o invólucro divcom style="white-space:pre-wrap;".
quer
1
O comentário de @Stewie funciona perfeitamente para mim (AngularJS 1.2.18), mostra explicitamente como estilizar o elemento individual (em oposição à solução de pilau e Paul Weber) e não é necessário alterar os estilos da tag <pre> como os outros proposto.
precisa
Você está certo, presumi que todo mundo sabe usar CSS básico e aplicar uma classe a um elemento. Se Stewie tivesse postado seu comentário como resposta, teria sido melhor para ele. Embora pareça como se ele tem pontos suficientes ...
Paul Weber
Concordo que @Stewie definitivamente deveria ter formatado seu comentário como resposta. Corrigiu meu problema perfeitamente.
CF_HoneyBadger 15/01

Respostas:

285

Com base na resposta de @pilau - mas com uma melhoria que nem a resposta aceita possui.

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

Isso usará novas linhas e espaços em branco, conforme indicado, mas também interromperá o conteúdo nos limites do conteúdo. Mais informações sobre a propriedade de espaço em branco podem ser encontradas aqui:

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

Se você deseja quebrar as novas linhas, mas também recolher vários espaços ou espaços em branco antes do texto (muito semelhante ao comportamento original do navegador), use-o como sugeriu @aaki:

white-space: pre-line;

Boa comparação dos diferentes modos de renderização: http://meyerweb.com/eric/css/tests/white-space.html

Paul Weber
fonte
1
A melhor solução aqui da IMO, pois ela não muda de estilo para uma fonte mono-espaçada como pré.
Troels Larsen
1
Observe o espaço em branco que precede o texto, que será preservado.
Silver Paladin
1
Desde que você o trouxe, não seria pre-lineo preferido? Está mais próximo da maneira como o HTML geralmente renderiza o conteúdo de texto de seus nós e ainda preserva as novas linhas.
aaki 27/01
Hmm ... você está certo, pré-linha é a melhor solução, depois que eu não tenho mais certeza do porquê de escolher pré-enrolamento em vez de pré-linha. Talvez o suporte ao navegador para pré-linha não seja tão bom? Mas vou acrescentar esta a resposta ... Aqui está uma comparação das representações: meyerweb.com/eric/css/tests/white-space.html
Paul Weber
Essa deve ser a resposta aceita! pre-lineé o caminho a percorrer. Obrigado Paul!
precisa saber é
126

Experimentar:

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

O <pre>invólucro imprimirá o texto com \no texto

Além disso, se você imprimir o json, para obter uma melhor aparência, use o jsonfiltro, como:

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

Demo

Eu concordo com @Paul Webera white-space: pre-wrap;melhor abordagem, de qualquer maneira, usando <pre>- o caminho mais rápido para depurar algumas coisas (se você não quiser perder tempo em estilizar)

Maxim Shoustin
fonte
O item.description é um texto que possui as \náreas que eu não conheço, não no final. Eu acho que preciso do com prebase em sua edição.
Diolor
29
Muitas vezes, uma tag <pre> não é uma boa solução, pois transforma o texto em courier e quebra o estilo da página. O estilo = "espaço em branco: pré-quebra;" solução parece ser uma solução melhor (pelo menos para a minha situação)
CF_HoneyBadger
1
@CF_HoneyBadger bem, para você @pilau's resposta é um adequado, mas isso não significa que a mina está errado e, portanto, eu tenho downvoted
Maxim Shoustin
Eu tentei converter tudo \npara <br/>'s' e, é claro, essas tags não estavam sendo renderizadas como marcação HTML ... depois de toda essa conversão encontrar sua stylesolução e isso é uma ajuda e simplificação incrível ... agora não sei tenho que continuar convertendo em torno de todos os meus dados de back-end e apenas fazer algumas alterações na exibição ... Você merece +1000!
Twknab 31/08/19
Isso funciona para o código, mas não para mostrar mensagens aos usuários, por exemplo. Eu acho que a resposta de Paulo é o correto
Quintonn
63

É tão simples com CSS (funciona, eu juro).

.angular-with-newlines {
  white-space: pre;
}
  • Olha ma! Sem tags HTML extras!
pilau
fonte
@pilau Quero embrulhar o texto se ele contiver vírgula (,) e não espaço em branco, como posso fazer isso?
Shylendra Madda
@shylendra minha solução não quebra texto, faz com que ele se comporte como se estivesse em uma pretag. Talvez abrir outra pergunta? Ou talvez eu tenha perdido o seu ponto?
pilau
Eu estava pensando sobre a compatibilidade do navegador. De acordo com este gráfico, parece funcionar em todos os principais navegadores. É muito menos complicado do que substituir novas linhas por tags br. Obrigado! Apenas preste atenção para formatar o código, para que ele não contenha espaços, eles aparecerão, é claro. developer.mozilla.org/pt-BR/docs/Web/CSS/white-space
Paul Weber
Pode ser ainda melhor usar o espaço em branco: pre-wrap, caso contrário o conteúdo nunca será empacotado.
Paul Weber
16

Com CSS, isso pode ser alcançado facilmente.

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

Ou uma classe CSS pode ser criada para esse fim e pode ser usada em um arquivo CSS externo

Rehan
fonte
2

Bem, depende, se você deseja vincular dados, não deve haver formatação, caso contrário, você pode bind-htmle não description.replace(/\\n/g, '<br>') tem certeza de que é o que deseja.

Nicolas Brugneaux
fonte
1

a solução css funciona, no entanto, você realmente não tem controle sobre o estilo. No meu caso, eu queria um pouco mais de espaço após a quebra de linha. Aqui está uma diretiva que eu criei para lidar com isso (texto datilografado):

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

Usar:

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

Tudo o que faz é agrupar cada parte do texto em uma <p>tag. Depois disso, você pode modelá-lo como quiser.

Dmitry Efimenko
fonte
1

Basta adicionar isso aos seus estilos, isso funciona para mim

white-space: pre-wrap

Por esse texto, <textarea>pode ser exibido como está lá com espaços e freios de linha

HTML

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

CSS

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

Basta usar o estilo css "white-space: pre-wrap" e você deve estar pronto. Eu tive o mesmo problema em que preciso lidar com mensagens de erro para as quais as quebras de linha e os espaços em branco são realmente particulares. Acabei de adicionar este inline onde vinculava os dados e funciona como um encanto!

Siddhartha Thota
fonte
0

Eu tive um problema semelhante a você. Não estou muito interessado nas outras respostas aqui, porque elas realmente não permitem que você estilize o comportamento da nova linha com muita facilidade. Não tenho certeza se você tem controle sobre os dados originais, mas a solução que eu adotei foi mudar "itens" de uma matriz de seqüências de caracteres para uma matriz de matrizes, onde cada item na segunda matriz continha uma linha de texto . Dessa forma, você pode fazer algo como:

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

Dessa forma, você pode aplicar classes aos parágrafos e estilizá-las com CSS.

Chris Rae
fonte