angularjs换行过滤器没有其他html

时间:2012-12-20 03:12:32

标签: javascript html angularjs sanitization

我正在尝试将换行符(\n)转换为html br
根据{{​​3}},这就是我所拥有的:

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&gt; 5
  我还是不想要html&amp;东西在这里...

我希望它输出:

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

有没有办法实现这个目标?

7 个答案:

答案 0 :(得分:272)

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

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

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

这将解析并显示\ n作为新行。对我很有用。

此处为jsFiddle example

答案 1 :(得分: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>

答案 2 :(得分: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>

答案 3 :(得分: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's lite version of jQuery提供。

以下部分正在应用newline过滤器,该过滤器是使用$filter服务完成的。

在这里查看plunker:http://plnkr.co/edit/SEtHH5eUgFEtC92Czq7T?p=preview

答案 4 :(得分:6)

如果您不想使用无限字符串销毁布局,请使用pre-line:

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

答案 5 :(得分:2)

目前使用ng-bind-html对过滤器进行更新:

function wc(string, word) {
        var length = typeof string === "string" && typeof word === "string" && word.length,
            loop = length,
            index = 0,
            count = 0;
        while (loop) {
            index = string.indexOf(word, index);
            if (index !== -1) {
                count += 1;
                index += length;
            } else {
                loop = false;
            }
        }
        return count;
    }

var innerH1 = h1.innerHTML,
        findWord = "<br>";  
    var h1Check = document.createElement("div");    
    h1Check.style.display = "none";
    h1Check.innerHTML = (wc(innerH1, findWord));

并且不再需要noHTML过滤器。

white-space解决方案支持浏览器支持率低: http://caniuse.com/#search=tab-size

答案 6 :(得分:0)

在这方面迟到了,但我会建议一个小的改进来检查undefined / null字符串。

类似的东西:

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