Ich versuche, Zeilenumbrüche (\n
) in HTML br
s zu konvertieren.
Gemäß diese Diskussion in der Google-Gruppe habe ich Folgendes:
myApp.filter('newlines', function () {
return function(text) {
return text.replace(/\n/g, '<br/>');
}
});
Die Diskussion dort empfiehlt auch Folgendes in der Ansicht zu verwenden:
{{ dataFromModel | newline | html }}
Dies scheint den alten html
-Filter zu verwenden, während wir jetzt das ng-bind-html
-Attribut verwenden sollen.
Unabhängig davon stellt dies ein Problem dar: Ich möchte nicht, dass HTML aus der ursprünglichen Zeichenfolge (dataFromModel
) als HTML dargestellt wird. nur die br
.
Geben Sie beispielsweise die folgende Zeichenfolge an:
Während 7> 5
Ich möchte immer noch kein HTML & Zeug hier ...
Ich möchte, dass es ausgegeben wird:
While 7 > 5<br>I still don't want html & stuff in here...
Gibt es eine Möglichkeit, dies zu erreichen?
Anstatt sich mit neuen Direktiven zu beschäftigen, habe ich mich entschieden, nur zwei Filter zu verwenden:
App.filter('newlines', function () {
return function(text) {
return text.replace(/\n/g, '<br/>');
}
})
.filter('noHTML', function () {
return function(text) {
return text
.replace(/&/g, '&')
.replace(/>/g, '>')
.replace(/</g, '<');
}
});
Dann pfeife ich aus meiner Sicht eine in die andere:
<span ng-bind-html-unsafe="dataFromModel | noHTML | newlines"></span>
Vielleicht können Sie dies nur mit HTML, einem <preformated text>
-Weg erreichen? Es wird vermieden, Filter zu verwenden oder irgendeine Art von Verarbeitung durchzuführen.
Alles was Sie tun müssen, ist den Text innerhalb eines Elements anzuzeigen, das dieses CSS enthält:
<p style="white-space: pre;">{{ MyMultiLineText}}</p>
Dies wird analysiert und als neue Zeilen angezeigt. Funktioniert gut für mich.
Hier ein jsFiddle-Beispiel .
Eine einfachere Methode besteht darin, einen Filter zu erstellen, der den Text an jedem \n
in eine Liste aufteilt, und dann `ng-repeat zu verwenden.
Der Filter:
App.filter('newlines', function() {
return function(text) {
return text.split(/\n/g);
};
});
und in der HTML:
<span ng-repeat="line in (text | newlines) track by $index">
<p> {{line}}</p>
<br>
</span>
Ich weiß nicht, ob Angular über einen Dienst zum Entfernen von HTML verfügt, aber es scheint, dass Sie HTML entfernen müssen, bevor Sie den benutzerdefinierten newlines
-Filter übergeben. Wie ich es tun würde, ist eine benutzerdefinierte no-html
-Direktive, an die eine Bereichseigenschaft und der Name eines Filters übergeben werden, der nach dem Entfernen der html
angewendet werden soll.
<div no-html="data" post-filter="newlines"></div>
Hier ist die Implementierung
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);
};
});
Das wichtige Bit ist die Variable text
. Hier erstelle ich ein DOM-Zwischenelement, füge es mit der html
-Methode an den HTML-Code an und rufe dann nur den Text mit der text
-Methode ab. Beide Methoden werden von Angulars Lite-Version von jQuery bereitgestellt.
Der folgende Teil wendet den newline
-Filter an, der mit dem $filter
-Dienst ausgeführt wird.
Überprüfen Sie den Plunker hier: http://plnkr.co/edit/SEtHH5eUgFEtC92Czq7T?p=preview
Wenn Sie das Layout nicht mit endlosen Strings zerstören möchten, verwenden Sie pre-line:
<p style="white-space: pre-line;">{{ MyMultiLineText}}</p>
Eine Aktualisierung des Filters mit ng-bind-html wäre derzeit:
myApp.filter('newlines', function () {
return function(text) {
return text.replace(/( )? /g, '<br/>');
}
});
und der noHTML-Filter ist nicht mehr erforderlich.
die White-Space-Lösung hat eine geringe Browserunterstützung: http://caniuse.com/#search=tab-size
Etwas spät zur Party, aber ich würde eine kleine Verbesserung vorschlagen, um auf undefined/null-Strings zu prüfen.
So etwas wie:
.filter('newlines', function () {
return function(text) {
return (text) ? text.replace(/( )? /g, '<br/>') : text;
};
})
Oder (etwas enger)
.filter('newlines', function () {
return function(text) {
return (text instanceof String || typeof text === "string") ? text.replace(/( )? /g, '<br/>') : text;
};
})