Preserva le interruzioni di riga in angularjs


176

Ho visto questa domanda SO.

Il mio codice invece di ng-bind="item.desc"usa {{item.desc}}perché ho un ng-repeatprima.

Quindi il mio codice:

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

La descrizione dell'elemento contiene \nper le nuove righe che non vengono visualizzate.

Come può {{item.description}}visualizzare le newline facilmente supponendo che io abbia quanto ng-repeatsopra?


Metterlo in un tag <pre>?
aet

88
Dando uno stile alla confezione divcon style="white-space:pre-wrap;".
Stewie,

1
Il commento di @Stewie funziona perfettamente per me (AngularJS 1.2.18), mostra esplicitamente come modellare il singolo elemento (al contrario della soluzione di pilau e Paul Weber) e non c'è bisogno di cambiare gli stili del tag <pre> come altri proposto.
Andre Holzner,

Hai ragione, ho assunto che tutti sappiano usare i CSS di base e applicare una classe a un elemento. Se Stewie avesse pubblicato il suo commento come risposta, sarebbe stato meglio per lui. Anche se sembra che abbia abbastanza punti ...
Paul Weber,

Sono d'accordo, @Stewie avrebbe sicuramente dovuto formattare il suo commento come una risposta. Ha risolto perfettamente il mio problema.
CF_HoneyBadger,

Risposte:


285

Basato sulla risposta di @pilau - ma con un miglioramento che nemmeno la risposta accettata ha.

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

Ciò utilizzerà le nuove righe e gli spazi bianchi come indicato, ma interromperà anche il contenuto ai limiti del contenuto. Ulteriori informazioni sulla proprietà degli spazi bianchi sono disponibili qui:

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

Se vuoi interrompere le nuove righe, ma anche comprimere più spazi o spazi bianchi che precedono il testo (molto simile al comportamento del browser originale), puoi utilizzare, come suggerito da @aaki:

white-space: pre-line;

Bel confronto tra le diverse modalità di rendering: http://meyerweb.com/eric/css/tests/white-space.html


1
La migliore soluzione qui IMO, in quanto non restituisce un carattere mono-spaziato come pre.
Troels Larsen,

1
Guarda lo spazio bianco che precede il testo, che verrà conservato.
Silver Paladin,

1
Da quando l'hai tirato fuori non sarebbe pre-lineil preferito? È più vicino al modo in cui l'HTML di solito rende il contenuto del testo dei suoi nodi e conserva ancora le nuove righe.
aaki,

Hmm ... hai ragione, pre-line è la soluzione migliore, dopo che non sono più sicuro del perché scelgo pre-wrap anziché pre-line. Forse il supporto del browser per la pre-linea non è buono? Ma aggiungerò questo alla risposta ... Ecco un confronto dei rendering: meyerweb.com/eric/css/tests/white-space.html
Paul Weber,

Questa dovrebbe essere la risposta accettata! pre-lineè la strada da percorrere. Grazie Paolo!
Demisx

126

Provare:

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

Il <pre>wrapper stamperà il testo \ncome testo

anche se si stampa il json, per un aspetto migliore utilizzare il jsonfiltro, come:

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

Demo

Sono d'accordo con @Paul Weberquesto white-space: pre-wrap;è un approccio migliore, comunque usando <pre>- il modo rapido principalmente per il debug di alcune cose (se non vuoi perdere tempo con lo styling)


La voce item.description è un testo che contiene le \naree che non conosco, non alla fine. Penso di aver bisogno del prebasato sulla tua modifica.
Diolor,

29
Molte volte, un tag <pre> non è una buona soluzione poiché trasforma il testo in corriere e spezza lo stile della pagina. Lo stile = "white-space: pre-wrap;" soluzione sembra essere una soluzione migliore (almeno per la mia situazione)
CF_HoneyBadger

1
@CF_HoneyBadger bene, per te @pilaula risposta è corretta, ma ciò non significa che la mia sia sbagliata e quindi sono stato retrocesso
Maxim Shoustin

Ho provato a convertire tutto in \n"s <br/>" e poi ovviamente questi tag non venivano resi come markup HTML ... dopo che tutto questo convertito ha trovato la tua stylesoluzione e questo è un aiuto e una semplificazione incredibili ... ora no devo continuare a convertire tutti i miei dati di backend e apportare solo alcune modifiche nella vista ... Ti meriti +1000!
twknab,

Questo funziona per il codice, ma non per mostrare messaggi agli utenti, ad esempio. Penso che la risposta di Paul sia quella corretta
Quintonn,

63

È così semplice con CSS (funziona, lo giuro).

.angular-with-newlines {
  white-space: pre;
}
  • Guarda mamma! Nessun tag HTML aggiuntivo!

@pilau Voglio racchiudere il testo se contiene una virgola (,) non uno spazio bianco come posso fare?
Shylendra Madda,

@shylendra la mia soluzione non racchiude il testo, lo fa comportare come se fosse in un pretag. Forse aprire un'altra domanda? O forse ho perso il tuo punto?
pilau,

Mi chiedevo sulla compatibilità del browser. Secondo questo grafico, sembra funzionare in tutti i principali browser. È molto meno seccante rispetto alla sostituzione di nuove righe con tag br. Grazie! Fai solo attenzione a formattare il codice in modo che non contenga spazi, verranno visualizzati ovviamente. developer.mozilla.org/en-US/docs/Web/CSS/white-space
Paul Weber

Potrebbe essere ancora meglio usare lo spazio bianco: pre-wrapping, altrimenti il ​​contenuto non si avvolgerà mai.
Paul Weber,

16

Con CSS questo può essere raggiunto facilmente.

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

Oppure una classe CSS può essere creata a questo scopo e può essere utilizzata da un file CSS esterno


2

Beh, dipende, se vuoi associare i dati, non dovrebbe esserci alcuna formattazione, altrimenti puoi bind-htmle non sei description.replace(/\\n/g, '<br>') sicuro che sia quello che vuoi però.


1

la soluzione CSS funziona, tuttavia non si ottiene davvero il controllo sullo stile. Nel mio caso volevo un po 'più di spazio dopo l'interruzione di linea. Ecco una direttiva che ho creato per gestire questo (dattiloscritto):

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

Uso:

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

Tutto ciò che fa è avvolgere ogni parte del testo in un <p>tag. Dopodiché puoi modellarlo come preferisci.


1

Aggiungilo ai tuoi stili, questo funziona per me

white-space: pre-wrap

Con questo testo in <textarea>può essere visualizzato in quanto è lì con spazi e freni di linea

HTML

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

CSS

.text-style{
    white-space: pre-wrap
}


0

Usa semplicemente lo stile CSS "white-space: pre-wrap" e dovresti essere pronto. Ho avuto lo stesso problema in cui ho bisogno di gestire i messaggi di errore per i quali le interruzioni di riga e gli spazi bianchi sono davvero particolari. Ho appena aggiunto questo inline dove stavo vincolando i dati e funziona come Charm!


0

Ho avuto un problema simile a te. Non sono così appassionato delle altre risposte qui perché non ti permettono davvero di modellare il comportamento newline molto facilmente. Non sono sicuro che tu abbia il controllo sui dati originali, ma la soluzione che ho adottato è stata quella di passare da "elementi" da array di stringhe a array di array, in cui ogni elemento nel secondo array conteneva una riga di testo . In questo modo puoi fare qualcosa come:

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

In questo modo puoi applicare le classi ai paragrafi e modellarle in modo gradevole con i CSS.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.