2015-09-11 3 views
3

В настоящее время я работаю с ng-bind-html. В основном, что я пытаюсь сделать, когда я публикую блог, блог содержит ссылки и другие стили. Поэтому, когда я пытаюсь показать список блогов, я использую нг-Бинг-HTML, как это:Angularjs ng-bind-html с пользовательским фильтром

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

, который работает отлично.

Но, кроме того, я пытаюсь обрезать блог и показывать только несколько абзацев с дополнительной опцией, передавая собственный фильтр. Но когда я прохожу фильтр я получаю следующее:

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

Мой фильтр выглядит следующим образом:

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; 
     } 
    } 
+1

Robinson - Кажется, ваш фильтр работает первым и обрезает HTML. Затем ng-bind-html пытается проанализировать недопустимую строку HTML, дающую вам ошибку. –

+0

Вы можете изменить свой фильтр, чтобы использовать код, указанный Minouris в этом решении, и посмотреть, не делает ли это трюк. http://stackoverflow.com/questions/3822233/javascript-truncate-html-text –

+0

Спасибо, я буду @ user1! –

ответ

0

Я использовал решение, отправленный Minouris в этом посте (Javascript truncate HTML text) и адаптировать его в 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; 
} 
    }); 

Рабочая plunkr: http://plnkr.co/edit/oCwmGyBXB26omocT2q9m?p=preview

Я гавань протестировали выше решение, и вы можете столкнуться с проблемами с более сложными HTML строк. Могу ли я предложить использовать библиотеку JQuery, например https://github.com/pathable/truncate?

Смежные вопросы