angularjs başka html içermeyen yeni satır filtresi


87

Satırsonu karakterlerini ( \n) html br' lere dönüştürmeye çalışıyorum .
Gereğince Google Grubundaki bu tartışma burada bende ne var:

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

Oradaki tartışma, aşağıdaki görünümde de kullanılmasını tavsiye eder:

{{ dataFromModel | newline | html }}

Görünüşe göre bu eski htmlfiltreyi kullanıyor , halbuki şimdi ng-bind-htmlözelliği kullanmamız gerekiyor .


Ne olursa olsun, bu bir sorun teşkil ediyor: Orijinal dizeden ( dataFromModel) herhangi bir HTML'nin HTML olarak gösterilmesini istemiyorum ; sadece br's.

Örneğin, aşağıdaki dize verildiğinde:

7> 5 iken
hala burada html ve şeyler istemiyorum ...

Çıktısını istiyorum:

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

Bunu başarmanın bir yolu var mı?

Yanıtlar:


280

Belki bunu sadece html ile başarabilirsin, bir <preformated text>yol? Filtre kullanmaktan veya her türlü işlemden kaçınacaktır.

Tek yapmanız gereken, metni bu CSS'ye sahip bir öğenin içinde görüntülemek:

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

Bu ayrıştırılacak ve \ n yeni satırlar olarak görüntülenecektir. Benim için harika çalışıyor.

Burada bir jsFiddle örneği .


79
ön hat, benim için daha iyi bir seçenekti.
Pepijn

7
+1, bu açık ara en basit çözüm ve birçok ihtiyaç için uygun görünüyor. Aslında, pre-lineuzun sıralar sarılacağından (herhangi bir <br>temel çözümde olduğu gibi) muhtemelen genel olarak daha iyidir .
tuomassalo

13
style = "beyaz boşluk: ön satır;" <div> içinde kullanmak daha iyi bir seçenek, bence
Dmitri Algazin

7
pre-wrapçoğu insan (değil pre-line) istediğini gibi görünüyor: "Boşluk tarayıcı tarafından korunur Metin gerektiğinde sarmak ve satır sonları üzerinde olacaktır." adresinden W3Schools'da
qwertzguy

2
<p> Chrome'un metnimin önüne fazladan satır eklemesini durdurmak için <p> üzerinde ng-bind = "MyMultiLineText" kullanmam gerektiğini fark ettim
Scott Warren

33

Yeni direktiflerle uğraşmak yerine, sadece 2 filtre kullanmaya karar verdim:

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

Sonra, benim görüşüme göre, birini diğerine aktarıyorum:

<span ng-bind-html-unsafe="dataFromModel | noHTML | newlines"></span>

Yeni satırlar için normal ifadeniz işe yaramaz. İhtiyacınız olan: text.replace(/\\n/g, '<br />')veya daha iyisitext.replace(/(\\r)?\\n/g, '<br />')
Bartłomiej Zalewski

2
@BarthZalewski - Bir dizeden bir normal ifadeyi derlerken yalnızca `\` 'ye ihtiyacınız vardır. Bir normal ifadeyi kullanırken eğik çizgiden kaçmanız gerekmez.
MegaHit

2
Ng-bind-html-unsafe kullanımdan kaldırıldığı için bu kod artık çalışmıyor.
Abhi

1
Artık isterseniz noHtml filtresini atlayabilir ve sadece newLines filtresini ng-bind-html'ye ekleyebilirsiniz. ngSanitize gerisini halleder.
Dave Merwin

26

Bunu yapmanın daha basit bir yolu, her birindeki metni \nbir listeye bölen bir filtre yapmak ve ardından `ng-tekrar kullanmaktır.

Filtre:

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

ve html'de:

<span ng-repeat="line in (text | newlines) track by $index">
    <p> {{line}}</p>
    <br>
</span>

4
Bu çözümü beğendim, ancak daha basit bir HTML kullanacağım:<p ng-repeat="line in (line.message | newlines)">{{line}}</p>
Thomas Fankhauser

2
Cevap İyi, ama daha iyi kullanımı track by: bir hata gündeme getireceğini yinelenen hatları, söz konusu line in (text | newlines) track by $index.
JellicleCat

11

Düzeni sonsuz dizelerle yok etmek istemiyorsanız, satır öncesi kullanın:

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

6

Angular'ın html'yi soymak için bir hizmeti olup olmadığını bilmiyorum, ancak newlinesözel filtrenizi geçmeden önce html'yi kaldırmanız gerekiyor gibi görünüyor . Bunu yapmamın yolu no-html, bir kapsam özelliği ve kaldırıldıktan sonra uygulanacak bir filtrenin adı olan özel bir yönergedir.html

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

İşte uygulama

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

Önemli olan bit textdeğişkendir. Burada bir ara DOM öğesi oluşturuyorum ve htmlyöntemi kullanarak HTML'ye ekliyorum ve ardından yalnızca textyöntemle metni alıyorum . Her iki yöntem de Angular'ın jQuery'nin lite sürümü tarafından sağlanır .

Aşağıdaki bölüm servis newlinekullanılarak yapılan filtreyi uygulamaktır $filter.

Plunker'ı buradan kontrol edin: http://plnkr.co/edit/SEtHH5eUgFEtC92Czq7T?p=preview


2

Şu anda ng-bind-html ile filtre güncellemesi şu şekilde olacaktır:

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

ve noHTML filtresi artık gerekli değildir.

beyaz alan çözümü düşük tarayıcı desteğine sahip: http://caniuse.com/#search=tab-size


0

Partiye bu konuda biraz geç, ancak tanımsız / boş dizeleri kontrol etmek için küçük bir iyileştirme öneririm.

Gibi bir şey:

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

Veya (biraz daha sıkı)

.filter('newlines', function () {
    return function(text) {
        return (text instanceof String || typeof text === "string") ? text.replace(/(&#13;)?&#10;/g, '<br/>') : text;
    };
})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.