Angularjs ng-bind-html与自定义过滤器

时间:2022-11-26 23:55:20

I am currently working with ng-bind-html. Basically, what I am trying to do is, when I post a blog, the blog contains links and other styling. So when I am trying to show the list of blogs, I am using ng-bing-html like this:

我目前正在使用ng-bind-html。基本上,我想要做的是,当我发布博客时,博客包含链接和其他样式。因此,当我试图显示博客列表时,我正在使用这样的ng-bing-html:

<p ng-bind-html="blog.blogContent"></p>

which works fine.

哪个工作正常。

But in addition, I try to truncate the blog and show only few paragraphs with view more option by passing a custom filter. But when I pass the filter I get the following:

但另外,我试图通过传递自定义过滤器来截断博客并仅显示几个带有查看更多选项的段落。但是当我通过过滤器时,我得到以下内容:

<p ng-bind-html="blog.blogContent | Truncate"></p>

Error: [$sanitize:badparse] The sanitizer was unable to parse the
following block of html: <a href="https:.......

My Filter looks like this:

我的过滤器看起来像这样:

return function (text, length, end) {
    if (text !== undefined) {
      if (isNaN(length)) {
        length = 450;
      }

      if (end === undefined) {
        end = ".......";
      }

      if (text.length <= length || text.length - end.length <= length) {
        return text;
      } else {
        return String(text).substring(0, length - end.length) + end;
      }
    }

2 个解决方案

#1


1  

You can solve this using custom directives and filters. try this one: https://*.com/a/45076560/6816707

您可以使用自定义指令和过滤器来解决此问题。试试这个:https://*.com/a/45076560/6816707

#2


0  

I used the solution posted by Minouris in this post (Javascript truncate HTML text) and adapted it into an AngularJS filter. It seems to work pretty well. The filter is

我在这篇文章中使用了Minouris发布的解决方案(Javascript截断HTML文本)并将其改编为AngularJS过滤器。它似乎工作得很好。过滤器是

angular.module('plunker').filter('Truncate', function() {
  return function(text, length, end) {
       if (text !== undefined) {
      if (isNaN(length)) {
        length = 20;
      }

      if (end === undefined) {
        end = ".......";
      }

      if (text.length <= length || text.length - end.length <= length) {
        return text;
      }

    var truncated = text.substring(0, length);
    // Remove line breaks and surrounding whitespace
    truncated = truncated.replace(/(\r\n|\n|\r)/gm,"").trim();
    // If the text ends with an incomplete start tag, trim it off
    truncated = truncated.replace(/<(\w*)(?:(?:\s\w+(?:={0,1}(["']{0,1})\w*\2{0,1})))*$/g, '');
    // If the text ends with a truncated end tag, fix it.
    var truncatedEndTagExpr = /<\/((?:\w*))$/g;
    var truncatedEndTagMatch = truncatedEndTagExpr.exec(truncated);
    if (truncatedEndTagMatch != null) {
        var truncatedEndTag = truncatedEndTagMatch[1];
        // Check to see if there's an identifiable tag in the end tag
        if (truncatedEndTag.length > 0) {
            // If so, find the start tag, and close it
            var startTagExpr = new RegExp(
                "<(" + truncatedEndTag + "\\w?)(?:(?:\\s\\w+(?:=([\"\'])\\w*\\2)))*>");
            var testString = truncated;
            var startTagMatch = startTagExpr.exec(testString);

            var startTag = null;
            while (startTagMatch != null) {
                startTag = startTagMatch[1];
                testString = testString.replace(startTagExpr, '');
                startTagMatch = startTagExpr.exec(testString);
            }
            if (startTag != null) {
                truncated = truncated.replace(truncatedEndTagExpr, '</' + startTag + '>');
            }
        } else {
            // Otherwise, cull off the broken end tag
            truncated = truncated.replace(truncatedEndTagExpr, '');
        }
    }
    // Now the tricky part. Reverse the text, and look for opening tags. For each opening tag,
    //  check to see that he closing tag before it is for that tag. If not, append a closing tag.
    var testString = reverseHtml(truncated);
    var reverseTagOpenExpr = /<(?:(["'])\w*\1=\w+ )*(\w*)>/;
    var tagMatch = reverseTagOpenExpr.exec(testString);
    while (tagMatch != null) {
        var tag = tagMatch[0];
        var tagName = tagMatch[2];
        var startPos = tagMatch.index;
        var endPos = startPos + tag.length;
        var fragment = testString.substring(0, endPos);
        // Test to see if an end tag is found in the fragment. If not, append one to the end
        //  of the truncated HTML, thus closing the last unclosed tag
        if (!new RegExp("<" + tagName + "\/>").test(fragment)) {
            truncated += '</' + reverseHtml(tagName) + '>';
        }
        // Get rid of the already tested fragment
        testString = testString.replace(fragment, '');
        // Get another tag to test
        tagMatch = reverseTagOpenExpr.exec(testString);
    }
    return truncated;
  }
  }

  function reverseHtml(str) {
    var ph = String.fromCharCode(206);
    var result = str.split('').reverse().join('');
    while (result.indexOf('<') > -1) {
        result = result.replace('<',ph);
    }
    while (result.indexOf('>') > -1) {
        result = result.replace('>', '<');
    }
    while (result.indexOf(ph) > -1) {
        result = result.replace(ph, '>');
    }
    return result;
}
  });

Working plunkr: http://plnkr.co/edit/oCwmGyBXB26omocT2q9m?p=preview

工作人员:http://plnkr.co/edit/oCwmGyBXB26omocT2q9m?p =preview

I havent tested the above solution and you may run into issues with more complicated HTML strings. May I suggest using a Jquery library like https://github.com/pathable/truncate to be safe?

我没有测试上面的解决方案,你可能会遇到更复杂的HTML字符串问题。我建议使用像https://github.com/pathable/truncate这样的Jquery库来保证安全吗?

#1


1  

You can solve this using custom directives and filters. try this one: https://*.com/a/45076560/6816707

您可以使用自定义指令和过滤器来解决此问题。试试这个:https://*.com/a/45076560/6816707

#2


0  

I used the solution posted by Minouris in this post (Javascript truncate HTML text) and adapted it into an AngularJS filter. It seems to work pretty well. The filter is

我在这篇文章中使用了Minouris发布的解决方案(Javascript截断HTML文本)并将其改编为AngularJS过滤器。它似乎工作得很好。过滤器是

angular.module('plunker').filter('Truncate', function() {
  return function(text, length, end) {
       if (text !== undefined) {
      if (isNaN(length)) {
        length = 20;
      }

      if (end === undefined) {
        end = ".......";
      }

      if (text.length <= length || text.length - end.length <= length) {
        return text;
      }

    var truncated = text.substring(0, length);
    // Remove line breaks and surrounding whitespace
    truncated = truncated.replace(/(\r\n|\n|\r)/gm,"").trim();
    // If the text ends with an incomplete start tag, trim it off
    truncated = truncated.replace(/<(\w*)(?:(?:\s\w+(?:={0,1}(["']{0,1})\w*\2{0,1})))*$/g, '');
    // If the text ends with a truncated end tag, fix it.
    var truncatedEndTagExpr = /<\/((?:\w*))$/g;
    var truncatedEndTagMatch = truncatedEndTagExpr.exec(truncated);
    if (truncatedEndTagMatch != null) {
        var truncatedEndTag = truncatedEndTagMatch[1];
        // Check to see if there's an identifiable tag in the end tag
        if (truncatedEndTag.length > 0) {
            // If so, find the start tag, and close it
            var startTagExpr = new RegExp(
                "<(" + truncatedEndTag + "\\w?)(?:(?:\\s\\w+(?:=([\"\'])\\w*\\2)))*>");
            var testString = truncated;
            var startTagMatch = startTagExpr.exec(testString);

            var startTag = null;
            while (startTagMatch != null) {
                startTag = startTagMatch[1];
                testString = testString.replace(startTagExpr, '');
                startTagMatch = startTagExpr.exec(testString);
            }
            if (startTag != null) {
                truncated = truncated.replace(truncatedEndTagExpr, '</' + startTag + '>');
            }
        } else {
            // Otherwise, cull off the broken end tag
            truncated = truncated.replace(truncatedEndTagExpr, '');
        }
    }
    // Now the tricky part. Reverse the text, and look for opening tags. For each opening tag,
    //  check to see that he closing tag before it is for that tag. If not, append a closing tag.
    var testString = reverseHtml(truncated);
    var reverseTagOpenExpr = /<(?:(["'])\w*\1=\w+ )*(\w*)>/;
    var tagMatch = reverseTagOpenExpr.exec(testString);
    while (tagMatch != null) {
        var tag = tagMatch[0];
        var tagName = tagMatch[2];
        var startPos = tagMatch.index;
        var endPos = startPos + tag.length;
        var fragment = testString.substring(0, endPos);
        // Test to see if an end tag is found in the fragment. If not, append one to the end
        //  of the truncated HTML, thus closing the last unclosed tag
        if (!new RegExp("<" + tagName + "\/>").test(fragment)) {
            truncated += '</' + reverseHtml(tagName) + '>';
        }
        // Get rid of the already tested fragment
        testString = testString.replace(fragment, '');
        // Get another tag to test
        tagMatch = reverseTagOpenExpr.exec(testString);
    }
    return truncated;
  }
  }

  function reverseHtml(str) {
    var ph = String.fromCharCode(206);
    var result = str.split('').reverse().join('');
    while (result.indexOf('<') > -1) {
        result = result.replace('<',ph);
    }
    while (result.indexOf('>') > -1) {
        result = result.replace('>', '<');
    }
    while (result.indexOf(ph) > -1) {
        result = result.replace(ph, '>');
    }
    return result;
}
  });

Working plunkr: http://plnkr.co/edit/oCwmGyBXB26omocT2q9m?p=preview

工作人员:http://plnkr.co/edit/oCwmGyBXB26omocT2q9m?p =preview

I havent tested the above solution and you may run into issues with more complicated HTML strings. May I suggest using a Jquery library like https://github.com/pathable/truncate to be safe?

我没有测试上面的解决方案,你可能会遇到更复杂的HTML字符串问题。我建议使用像https://github.com/pathable/truncate这样的Jquery库来保证安全吗?