没有其他HTML的angularjs换行过滤器


86

我正在尝试将换行符(\n)转换为html br
根据Google网上论坛的讨论,这是我得到的:

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

那里的讨论还建议在视图中使用以下内容:

{{ dataFromModel | newline | html }}

这似乎正在使用旧的html过滤器,而现在我们应该使用ng-bind-html属性。


无论如何,这带来了一个问题:我不希望原始字符串(dataFromModel)中的任何HTML都呈现为HTML;只有br的。

例如,给定以下字符串:

虽然7> 5,但
我仍然不想要html和其他东西在这里...

我希望它输出:

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

有什么办法可以做到这一点?

Answers:


278

也许您只能使用html来实现这一目标<preformated text>?它将避免使用过滤器或进行任何类型的处理。

您所要做的就是在具有以下CSS的元素中显示文本:

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

这将解析并将\ n显示为新行。对我来说很棒。

这里是一个jsFiddle示例


79
前线,对我来说是一个更好的选择。
Pepijn

7
+1,这是迄今为止最简单的解决方案,似乎可以满足许多需求。实际上,pre-line总体上可能会更好,因为长行将被包装(就像使用任何<br>基础解决方案一样)。
tuomassalo 2013年

13
style =“ white-space:pre-line;” 我认为,在<div>内部使用是更好的选择
Dmitri Algazin 2014年

7
pre-wrap似乎是大多数人想要的(而不是前行):w3schools的
qwertzguy 2014年

2
我发现我需要在<p>上使用ng-bind =“ MyMultiLineText”停止Chrome在我的文本前添加额外的行
Scott Warren

33

我决定不使用新的指令,而是决定使用2个过滤器:

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

然后,在我看来,我将一个管道插入另一个管道:

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

您的新行正则表达式将无法正常工作。您需要:text.replace(/\\n/g, '<br />')甚至更好text.replace(/(\\r)?\\n/g, '<br />')
巴特洛梅耶扎莱夫斯基

2
@BarthZalewski-从字符串编译一个正则表达式时只需要`\`。使用正则表达式文字时,您不必转义斜杠。
MegaHit 2014年

2
由于不建议使用ng-bind-html-unsafe,因此该代码不再起作用。
阿比

1
现在,您可以根据需要跳过noHtml过滤器,而只需将newLines过滤器添加到ng-bind-html。ngSanitize将负责其余的工作。
戴夫·默温

26

一种更简单的方法是制作一个过滤器,将每个文本\n分成一个列表,然后使用ng-repeat。

过滤器:

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

并在html中:

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

4
我喜欢这种解决方案,但是会使用更简单的HTML:<p ng-repeat="line in (line.message | newlines)">{{line}}</p>
Thomas Fankhauser

2
好的答案,但是track by在重复行的情况下更好地使用,这会引发错误:line in (text | newlines) track by $index
JellicleCat 2014年


6

我不知道Angular是否具有剥离html的服务,但是看来您需要在通过newlines自定义过滤器之前删除html 。我的方式是通过自定义no-html指令,该指令将传递一个范围属性和一个删除过滤器后要应用的过滤器的名称。html

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

这是实现

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

重要的是text变量。在这里,我创建了一个中间DOM元素,并使用html方法将其附加到HTML ,然后仅使用text。两种方法均由Angular的精简版jQuery提供

以下部分适用于 newline过滤器,这是通过$filter服务完成的。

在此处检查活塞:http ://plnkr.co/edit/SEtHH5eUgFEtC92Czq7T?p=preview



0

在这方面晚了一点,但我建议对检查未定义/空字符串进行一些改进。

就像是:

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

或(位偏紧)

.filter('newlines', function () {
    return function(text) {
        return (text instanceof String || typeof text === "string") ? text.replace(/(&#13;)?&#10;/g, '<br/>') : text;
    };
})
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.