【问题标题】:angularjs newline filter with no other html没有其他html的angularjs换行过滤器
【发布时间】:2012-12-07 12:49:16
【问题描述】:

我正在尝试将换行符 (\n) 转换为 html br's。
根据this discussion in the Google Group,这就是我所拥有的:

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...

有没有办法做到这一点?

【问题讨论】:

    标签: javascript html angularjs sanitization


    【解决方案1】:

    也许你只能通过 html 实现这一点,&lt;preformated text&gt; 方式?它将避免使用过滤器或进行任何类型的处理。

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

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

    这会将 \n 解析并显示为新行。非常适合我。

    这里是jsFiddle example

    【讨论】:

    • 预线,对我来说是一个更好的选择。
    • +1,这是迄今为止最简单的解决方案,似乎适合许多需求。实际上,pre-line 通常可能更好,因为长行将被包装(就像任何基于 &lt;br&gt; 的解决方案一样)。
    • style="white-space: pre-line;"在我看来,在
      中使用是更好的选择
    • pre-wrap 似乎是大多数人想要的(不是前行):“空白由浏览器保留。文本将在必要时换行,并在换行符处”来自w3schools跨度>
    • 我发现我需要在

      上使用 ng-bind="MyMultiLineText" 来阻止 Chrome 在我的文本前面添加额外的行

    【解决方案2】:

    我决定只使用 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, '&lt;br /&gt;') 或者更好的text.replace(/(\\r)?\\n/g, '&lt;br /&gt;')
    • @BarthZalewski - 从字符串编译正则表达式时,您只需要 `\`。使用正则表达式时,您不必转义斜杠。
    • 此代码不再有效,因为 ng-bind-html-unsafe 已被弃用。
    • 您现在可以根据需要跳过 noHtml 过滤器,只需将 newLines 过滤器添加到 ng-bind-html。 ngSanitize 会处理剩下的事情。
    【解决方案3】:

    更简单的方法是创建一个过滤器,将每个\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>
    

    【讨论】:

    • 我喜欢这个解决方案,但会使用更简单的 HTML:&lt;p ng-repeat="line in (line.message | newlines)"&gt;{{line}}&lt;/p&gt;
    • 好答案,但最好使用 track by 以防重复行,这会引发错误:line in (text | newlines) track by $index
    【解决方案4】:

    如果你不想用无尽的字符串破坏布局,请使用前行:

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

    【讨论】:

      【解决方案5】:

      我不知道 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 服务完成的。

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

      【讨论】:

        【解决方案6】:

        目前使用 ng-bind-html 对过滤器的更新是:

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

        并且不再需要 noHTML 过滤器。

        空白解决方案的浏览器支持较低: http://caniuse.com/#search=tab-size

        【讨论】:

          【解决方案7】:

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

          类似:

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

          【讨论】:

            猜你喜欢
            相关资源
            最近更新 更多
            热门标签