Zachowaj podziały wierszy w angularjs

176

Widziałem to TAK pytanie.

Mój kod zamiast ng-bind="item.desc"używa, {{item.desc}}ponieważ mam ng-repeatprzed.

Więc mój kod:

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

Opis pozycji zawiera \nznaki nowej linii, które nie są renderowane.

Jak można {{item.description}}łatwo wyświetlać znaki nowej linii, zakładając, że mam ng-repeatpowyższe?

Diolor
źródło
Umieścić go w tagu <pre>?
aet
88
Stylizując opakowanie za divpomocą style="white-space:pre-wrap;".
Stewie
1
Komentarz @Stewie działa idealnie dla mnie (AngularJS 1.2.18), wyraźnie pokazuje, jak stylizować pojedynczy element (w przeciwieństwie do rozwiązania Pilau i Paula Webera) i nie ma potrzeby zmieniania stylów znacznika <pre> jak inne proponowane.
Andre Holzner
Masz rację, założyłem, że każdy wie, jak użyć podstawowego css i zastosować klasę do elementu. Gdyby Stewie zamieścił swój komentarz jako odpowiedź, byłoby lepiej dla niego. Choć wydaje się, że ma wystarczająco dużo punktów ...
Paul Weber
Zgadzam się, @Stewie zdecydowanie powinien był sformatować swój komentarz jako odpowiedź. To doskonale rozwiązało mój problem.
CF_HoneyBadger,

Odpowiedzi:

285

Na podstawie odpowiedzi @pilau - ale z poprawą, której nie ma nawet zaakceptowana odpowiedź.

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

Spowoduje to użycie podanych nowych linii i białych znaków, ale także złamanie zawartości na granicach zawartości. Więcej informacji na temat właściwości białych znaków można znaleźć tutaj:

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

Jeśli chcesz przerywać w nowych wierszach, ale także zwinąć wiele spacji lub odstępów poprzedzających tekst (bardzo podobne do zachowania oryginalnej przeglądarki), możesz użyć, zgodnie z sugestią @aaki:

white-space: pre-line;

Ładne porównanie różnych trybów renderowania: http://meyerweb.com/eric/css/tests/white-space.html

Paul Weber
źródło
1
Najlepsze rozwiązanie tutaj IMO, ponieważ nie zmienia stylu na czcionkę o mono-odstępach, jak pre.
Troels Larsen
1
Obserwuj odstępy poprzedzające tekst, który zostanie zachowany.
Silver Paladin
1
Skoro o tym pre-linewspomniałeś, czy nie byłby to preferowany? Jest bliżej sposobu, w jaki HTML zwykle renderuje zawartość tekstową swoich węzłów i nadal zachowuje znaki nowej linii.
aaki
Hmm ... masz rację, pre-line jest lepszym rozwiązaniem, skoro nie jestem już pewien, dlaczego wybieram pre-wrap zamiast pre-line. Może obsługa przeglądarki dla pre-line nie jest tak dobra? Ale dodam to do odpowiedzi ... Oto porównanie renderingów: meyerweb.com/eric/css/tests/white-space.html
Paul Weber
To powinna być akceptowana odpowiedź! pre-linejest droga do zrobienia. Dzięki Paul!
demisx
126

Próbować:

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

<pre>Wrapper będzie drukowanie tekstu z \njako tekst

również jeśli drukujesz json, dla lepszego wyglądu użyj jsonfiltra, takiego jak:

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

Demo

Zgadzam się z @Paul Webertym white-space: pre-wrap;jest lepsze podejście, w każdym razie użycie <pre>- najszybszy sposób głównie do debugowania niektórych rzeczy (jeśli nie chcesz tracić czasu na stylizację)

Maxim Shoustin
źródło
Element item.description to tekst, który zawiera \nobszary, których nie znam, a nie na końcu. Myślę, że potrzebuję na prepodstawie twojej edycji.
Diolor
29
Często tag <pre> nie jest dobrym rozwiązaniem, ponieważ przekształca tekst w przesyłkę kurierską i łamie styl strony. Styl = "white-space: pre-wrap;" rozwiązanie wydaje się być lepszym rozwiązaniem (przynajmniej w mojej sytuacji)
CF_HoneyBadger
1
@CF_HoneyBadger cóż, twoja @pilauodpowiedź jest właściwa, ale nie oznacza to, że moja jest zła i dlatego zostałem odrzucony
Maxim Shoustin
Próbowałem przekonwertować wszystko \nskończone na <br/>'s, a potem oczywiście te tagi nie były renderowane jako znaczniki HTML ... po tym wszystkim konwersja znalazła twoje stylerozwiązanie i jest to niesamowita pomoc i uproszczenie ... teraz nie Muszę konwertować wszystkie moje dane backendowe i po prostu wprowadzić kilka zmian w Widoku ... Zasługujesz na +1000!
twknab
Działa to w przypadku kodu, ale nie służy na przykład do wyświetlania wiadomości użytkownikom. Myślę, że odpowiedź Paula jest poprawna
Quintonn
63

To takie proste z CSS (przysięgam, działa).

.angular-with-newlines {
  white-space: pre;
}
  • Spójrz mamo! Bez dodatkowych tagów HTML!
pilaw
źródło
@pilau Chcę zawinąć tekst, jeśli zawiera przecinek (,), a nie spację, jak mogę to zrobić?
Shylendra Madda
@shylendra moje rozwiązanie nie zawija tekstu, sprawia, że ​​zachowuje się jak w pretagu. Może otworzysz kolejne pytanie? A może przegapiłem twój punkt widzenia?
pilau
Zastanawiałem się nad kompatybilnością przeglądarki. Zgodnie z tym wykresem wydaje się, że działa we wszystkich głównych przeglądarkach. Jest to o wiele mniej kłopotliwe niż zastępowanie znaków nowej linii znacznikami br. Dzięki! Po prostu zwróć uwagę na sformatowanie kodu, aby nie zawierał spacji, oczywiście się pojawią. developer.mozilla.org/en-US/docs/Web/CSS/white-space
Paul Weber
Jeszcze lepiej byłoby użyć białych znaków: zawijanie wstępne, w przeciwnym razie zawartość nigdy się nie zawinie.
Paul Weber
16

Dzięki CSS można to łatwo osiągnąć.

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

W tym celu można też utworzyć klasę CSS i używać jej z zewnętrznego pliku CSS

Rehan
źródło
2

Cóż, to zależy, jeśli chcesz powiązać dane, nie powinno być w tym żadnego formatowania, w przeciwnym razie możesz bind-htmli nie jesteś description.replace(/\\n/g, '<br>') pewien, czy tego chcesz.

Nicolas Brugneaux
źródło
1

rozwiązanie CSS działa, ale tak naprawdę nie masz kontroli nad stylizacją. W moim przypadku chciałem trochę więcej miejsca po przełamaniu linii. Oto dyrektywa, którą stworzyłem, aby sobie z tym poradzić (maszynopis):

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

Posługiwać się:

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

Wszystko, co robi, to zawija każdą część tekstu w <p>znacznik. Następnie możesz stylizować, jak chcesz.

Dmitry Efimenko
źródło
1

Po prostu dodaj to do swoich stylów, to działa dla mnie

white-space: pre-wrap

Dzięki temu tekstowi <textarea>można wyświetlić, ponieważ jest tam ze spacjami i przerwami w linii

HTML

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

CSS

.text-style{
    white-space: pre-wrap
}
Akitha_MJ
źródło
0

Po prostu użyj stylu „white-space: pre-wrap” w stylu css i wszystko będzie dobrze. Miałem ten sam problem, w którym muszę obsługiwać komunikaty o błędach, dla których podziały wierszy i spacje są naprawdę szczególne. Właśnie dodałem to w wierszu, w którym wiązałem dane i działa jak Urok!

Siddhartha Thota
źródło
0

Miałem z tobą podobny problem. Nie przepadam za innymi odpowiedziami, ponieważ nie pozwalają one na łatwe stylizowanie zachowania nowej linii. Nie jestem pewien, czy masz kontrolę nad oryginalnymi danymi, ale rozwiązanie, które zastosowałem, polegało na przełączeniu „elementów” z tablicy ciągów na tablicę tablic, w której każdy element w drugiej tablicy zawierał wiersz tekstu . W ten sposób możesz zrobić coś takiego:

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

W ten sposób możesz stosować klasy do akapitów i ładnie je stylizować za pomocą CSS.

Chris Rae
źródło