2016-12-26 4 views
0

Я добавляю директиву readmore в угловое приложение. Чтение больше работает отлично, но попробуйте использовать фильтр для текста, и он не интерпретирует строку фильтра правильно.Почему угловая директива отключает текстовый фильтр?

Пример: http://plnkr.co/edit/Tsqkv1nd6CC8e5Kr9pdU?p=preview

Изменить демонстрационный текст ниже код, чтобы увидеть, что происходит:

<p read-more>(1) This is a short paragraph.</p> 
<p read-more>(2) This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph.</p> 
<p>(3) {{desc}}</p> 
<p read-more>(4) {{desc}}</p> 

Обратите внимание на 3 и 4 примера использовать значение $ scope.desc, определенный в контроллере в приложении .js. # 3 работает. # 4 терпит неудачу. Зачем? Как исправить?

app.js:

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope) { 
    $scope.desc = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec rutrum vehicula tortor, vitae ornare nunc semper eu. Vivamus varius, eros vel tristique accumsan, libero nulla cursus ante, eu eleifend risus orci scelerisque nibh. Curabitur feugiat, augue ut commodo bibendum, nisi leo porttitor diam, tincidunt auctor tellus ante sit amet nibh. Duis velit libero, aliquam at felis eu, pellentesque mollis mi. Nam a est orci. Ut bibendum sagittis semper. Cras eget arcu non augue mollis aliquam. Ut ut gravida ligula. Nulla imperdiet lacinia mi, nec fringilla mauris interdum at. Phasellus gravida tempor varius. Cras molestie et nulla eget maximus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris aliquet malesuada feugiat. Curabitur fermentum bibendum nulla, non dictum ipsum tincidunt non. Quisque convallis pharetra tempor. Donec id pretium leo. Pellentesque luctus massa non elit viverra pellentesque. Cras vitae neque molestie, rhoncus ipsum sit amet, lobortis dui. Fusce in urna sem. Vivamus vehicula dignissim augue et scelerisque. Etiam quam nisi, molestie ac dolor in, tincidunt tincidunt arcu. Praesent sed justo finibus, fringilla velit quis, porta erat. Donec blandit metus ut arcu iaculis iaculis. Cras nec dolor fringilla justo ullamcorper auctor. Aliquam eget pretium velit. Morbi urna justo, pulvinar id lobortis in, aliquet placerat orci.'; 
}); 


app.directive('readMore', function() { 
    return { 
    restrict: 'A', 
    transclude: true, 
    replace: true, 
    template: '<p></p>', 
    scope: { 
     moreText: '@', 
     lessText: '@', 
     words: '@', 
     ellipsis: '@', 
     char: '@', 
     limit: '@', 
     content: '@' 
    }, 
    link: function(scope, elem, attr, ctrl, transclude) { 
     var moreText = angular.isUndefined(scope.moreText) ? ' <a class="read-more">Read More...</a>' : ' <a class="read-more">' + scope.moreText + '</a>', 
     lessText = angular.isUndefined(scope.lessText) ? ' <a class="read-less">Less ^</a>' : ' <a class="read-less">' + scope.lessText + '</a>', 
     ellipsis = angular.isUndefined(scope.ellipsis) ? '' : scope.ellipsis, 
     limit = angular.isUndefined(scope.limit) ? 150 : scope.limit; 

     attr.$observe('content', function(str) { 
     readmore(str); 
     }); 

     transclude(scope.$parent, function(clone, scope) { 
     readmore(clone.text().trim()); 
     }); 

     function readmore(text) { 

     var text = text, 
      orig = text, 
      regex = /\s+/gi, 
      charCount = text.length, 
      wordCount = text.trim().replace(regex, ' ').split(' ').length, 
      countBy = 'char', 
      count = charCount, 
      foundWords = [], 
      markup = text, 
      more = ''; 

     if (!angular.isUndefined(attr.words)) { 
      countBy = 'words'; 
      count = wordCount; 
     } 

     if (countBy === 'words') { // Count words 

      foundWords = text.split(/\s+/); 

      if (foundWords.length > limit) { 
      text = foundWords.slice(0, limit).join(' ') + ellipsis; 
      more = foundWords.slice(limit, count).join(' '); 
      markup = text + moreText + '<span class="more-text">' + more + lessText + '</span>'; 
      } 

     } else { // Count characters 

      if (count > limit) { 
      text = orig.slice(0, limit) + ellipsis; 
      more = orig.slice(limit, count); 
      markup = text + moreText + '<span class="more-text">' + more + lessText + '</span>'; 
      } 

     } 

     elem.append(markup); 
     elem.find('.read-more').on('click', function() { 
      $(this).hide(); 
      elem.find('.more-text').addClass('show').slideDown(); 
     }); 
     elem.find('.read-less').on('click', function() { 
      elem.find('.read-more').show(); 
      elem.find('.more-text').hide().removeClass('show'); 
     }); 

     } 
    } 
    }; 
}); 

style.css:

/* Put your css in here */ 

a.read-more, a.read-less { 
    cursor: pointer; 
    color: blue; 
    font-size: 0.8em; 
} 
span.more-text { 
    display: none; 
} 
span.more-text.show { 
     display: inline !important 
} 

index.html:

<!DOCTYPE html> 
<html ng-app="plunker"> 

<head> 
    <meta charset="utf-8" /> 
    <title>Angular Read More Directive</title> 
    <script> 
    document.write('<base href="' + document.location + '" />'); 
    </script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="jquery" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
    <script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js" data-semver="1.3.7"></script> 
    <script src="app.js"></script> 
</head> 

<body ng-controller="MainCtrl"> 
    <p read-more>This is a short paragraph.</p> 
    <p read-more>This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph.</p> 
    <p read-more>{{desc}}</p> 
</body> 

</html> 
+0

Пожалуйста, покажите весь соответствующий код в вопросе. Вопросы должны быть самодостаточными, и нам не нужно уходить с сайта, чтобы рассмотреть вашу проблему. Демонстрации велики, но должны поддерживать только то, что на самом деле существует в самом вопросе – charlietfl

ответ

1

В соответствии с текущей реализацией кода readmore становится вызывается перед transcluded Содержимое DOM проецируется на шаблон директивы.

В этом случае вы должны принять использование content атрибута просто говоря content="{{desc}}", что позволит вызвать readmore метод директивы, как attr.$observe метод уволят.

<p read-more content="{{desc}}">(4)</p> 

Demo Plunkr

+0

спасибо. что решило проблему. непонятно почему. как бы я изменил его, чтобы исходный html работал? –