filter baris baru angularjs tanpa html lain

87

Saya mencoba untuk mengubah karakter baris baru ( \n) menjadi html br.
Sesuai diskusi di Google Grup ini , inilah yang saya dapatkan:

myApp.filter('newlines', function () {
    return function(text) {
        return text.replace(/\n/g, '<br/>');
    }
});

Diskusi di sana juga menyarankan untuk menggunakan yang berikut ini dalam tampilan:

{{ dataFromModel | newline | html }}

Ini sepertinya menggunakan htmlfilter lama , sedangkan sekarang kita seharusnya menggunakan ng-bind-htmlatribut.


Terlepas dari itu, ini menimbulkan masalah: Saya tidak ingin HTML dari string asli ( dataFromModel) dirender sebagai HTML; hanya britu.

Misalnya, diberikan string berikut:

Sementara 7> 5
saya masih tidak ingin html & barang di sini ...

Saya ingin menghasilkan:

While 7 &gt; 5<br>I still don't want html &amp; stuff in here...

Apakah ada cara untuk melakukannya?

MegaHit
sumber

Jawaban:

280

Mungkin Anda bisa mencapai ini hanya dengan html, suatu <preformated text>cara? Ini akan menghindari penggunaan filter atau melakukan pemrosesan apa pun.

Yang harus Anda lakukan adalah menampilkan teks di dalam elemen yang memiliki CSS ini:

<p style="white-space: pre;">{{ MyMultiLineText}}</p>

Ini akan mengurai dan menampilkan \ n sebagai baris baru. Berfungsi bagus untuk saya.

Ini, contoh jsFiddle .

Devin Spikowski
sumber
79
pre-line, adalah pilihan yang lebih baik bagi saya.
Pepijn
7
+1, sejauh ini ini adalah solusi paling sederhana dan tampaknya sesuai untuk banyak kebutuhan. Memang, pre-linemungkin lebih baik secara umum, karena baris panjang akan dibungkus (seperti yang akan dilakukan dengan <br>solusi berbasis apa pun ).
tuomassalo
13
style = "white-space: pre-line;" adalah pilihan yang lebih baik untuk digunakan di dalam <div>, menurut pendapat saya
Dmitri Algazin
7
pre-wrapsepertinya yang diinginkan kebanyakan orang (bukan pra-baris): "Spasi kosong disimpan oleh browser. Teks akan ditutup bila perlu, dan saat jeda baris" dari w3schools
qwertzguy
2
Saya merasa saya perlu menggunakan ng-bind = "MyMultiLineText" di <p> ​​untuk menghentikan Chrome menambahkan baris tambahan di depan teks saya
Scott Warren
33

Alih-alih mengotak-atik arahan baru, saya memutuskan untuk hanya menggunakan 2 filter:

App.filter('newlines', function () {
    return function(text) {
        return text.replace(/\n/g, '<br/>');
    }
})
.filter('noHTML', function () {
    return function(text) {
        return text
                .replace(/&/g, '&amp;')
                .replace(/>/g, '&gt;')
                .replace(/</g, '&lt;');
    }
});

Kemudian, dalam pandangan saya, saya menyalurkan satu ke yang lain:

<span ng-bind-html-unsafe="dataFromModel | noHTML | newlines"></span>
MegaHit
sumber
Regex Anda untuk baris baru tidak akan berfungsi. Anda membutuhkan: text.replace(/\\n/g, '<br />')atau bahkan lebih baiktext.replace(/(\\r)?\\n/g, '<br />')
Bartłomiej Zalewski
2
@BarthZalewski - Anda hanya perlu `\` saat mengompilasi regex dari string. Saat menggunakan literal regex Anda tidak harus keluar dari garis miring.
MegaHit
2
Kode ini tidak lagi berfungsi karena ng-bind-html-unsafe tidak digunakan lagi.
Abhi
1
Anda sekarang dapat melewati filter noHtml jika Anda mau dan cukup menambahkan filter newLines ke ng-bind-html. ngSanitize akan mengurus sisanya.
Dave Merwin
26

Cara yang lebih sederhana untuk melakukannya adalah dengan membuat filter yang memisahkan teks di masing \n- masing menjadi daftar, lalu menggunakan `ng-repeat.

Filter:

App.filter('newlines', function() {
  return function(text) {
    return text.split(/\n/g);
  };
});

dan di html:

<span ng-repeat="line in (text | newlines) track by $index">
    <p> {{line}}</p>
    <br>
</span>
JJW5432
sumber
4
Saya suka solusi ini, tetapi akan menggunakan HTML yang lebih sederhana:<p ng-repeat="line in (line.message | newlines)">{{line}}</p>
Thomas Fankhauser
2
Baik jawaban, tapi lebih baik digunakan track bydalam kasus duplikat baris, yang akan meningkatkan kesalahan: line in (text | newlines) track by $index.
JellicleCat
11

Jika Anda tidak ingin menghancurkan tata letak dengan string tanpa akhir, gunakan pre-line:

<p style="white-space: pre-line;">{{ MyMultiLineText}}</p>
Sebastian Viereck
sumber
6

Saya tidak tahu apakah Angular memiliki layanan untuk menghapus html, tetapi tampaknya Anda perlu menghapus html sebelum meneruskan newlinesfilter kustom Anda . Cara saya melakukannya adalah melalui no-htmlarahan khusus , yang akan melewati properti cakupan dan nama filter untuk diterapkan setelah menghapushtml

<div no-html="data" post-filter="newlines"></div>

Berikut implementasinya

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

Bit yang penting adalah textvariabelnya. Di sini saya membuat elemen DOM perantara dan menambahkannya ke HTML menggunakan htmlmetode dan kemudian hanya mengambil teks dengan textmetode tersebut. Kedua metode ini disediakan oleh jQuery versi lite Angular .

Bagian berikut menerapkan newlinefilter, yang dilakukan dengan menggunakan $filterlayanan.

Periksa plunker di sini: http://plnkr.co/edit/SEtHH5eUgFEtC92Czq7T?p=preview

jaime
sumber
2

Pembaruan pada filter dengan ng-bind-html saat ini adalah:

myApp.filter('newlines', function () {
  return function(text) {
    return text.replace(/(&#13;)?&#10;/g, '<br/>');
  }
});

dan filter noHTML tidak lagi diperlukan.

solusi white-space memiliki dukungan browser yang rendah: http://caniuse.com/#search=tab-size

Alex Mounir
sumber
0

Agak terlambat ke pesta tentang ini tetapi saya akan menyarankan perbaikan kecil untuk memeriksa string yang tidak ditentukan / nol.

Sesuatu seperti:

.filter('newlines', function () {
    return function(text) {
        return (text) ? text.replace(/(&#13;)?&#10;/g, '<br/>') : text;
    };
})

Atau (sedikit lebih ketat)

.filter('newlines', function () {
    return function(text) {
        return (text instanceof String || typeof text === "string") ? text.replace(/(&#13;)?&#10;/g, '<br/>') : text;
    };
})
Ben Edge
sumber