Ограничьте длину строки с AngularJS


225

У меня есть следующее:

<div>{{modal.title}}</div>

Есть ли способ, которым я мог бы ограничить длину строки, чтобы сказать 20 символов?

И еще лучший вопрос был бы, есть ли способ, которым я мог бы изменить строку, которая будет обрезана и показать ...в конце, если это больше чем 20 символов?


Ответы:


344

Редактировать Последняя версия фильтраAngularJS предложений .limitTo

Вам нужен специальный фильтр, подобный этому:

angular.module('ng').filter('cut', function () {
        return function (value, wordwise, max, tail) {
            if (!value) return '';

            max = parseInt(max, 10);
            if (!max) return value;
            if (value.length <= max) return value;

            value = value.substr(0, max);
            if (wordwise) {
                var lastspace = value.lastIndexOf(' ');
                if (lastspace !== -1) {
                  //Also remove . and , so its gives a cleaner result.
                  if (value.charAt(lastspace-1) === '.' || value.charAt(lastspace-1) === ',') {
                    lastspace = lastspace - 1;
                  }
                  value = value.substr(0, lastspace);
                }
            }

            return value + (tail || ' …');
        };
    });

Использование:

{{some_text | cut:true:100:' ...'}}

Параметры:

  • wordwise (логическое) - если true, вырезать только по границам слов,
  • max (целое число) - максимальная длина текста, сокращенная до этого числа символов,
  • tail (string, default: '…') - добавить эту строку во входную строку, если строка была обрезана.

Другое решение : http://ngmodules.org/modules/angularjs-truncate (автор @Ehvince)


2
В angular-modules есть эквивалент: ngmodules.org/modules/angularjs-truncate
Ehvince

angularjs-truncate - это не решение, а ваше решение IS. Спасибо! Сделай это как модуль!
Антон Бессонов

@epokk Есть ли способ разрешить пользователю, после нажатия на три точки, показать полный неразрезанный текст? Как "показать больше"? Спасибо!
Фалес П

это работает нормально, когда мы используем его так {{post.post_content | cut: true: 100: '...'}} Но происходит сбой, когда я использую вот так <span ng-bind-html = "trustedHtml (post.post_content | cut: true: 100: '...')"> < / span> Потому что я вынужден использовать его с доверенным HTML в моем случае
S Vinesh

Словесный лимит - хорошая функция, которая, кажется, не существует в стандартном «limitTo»
pdizz,

496

Вот простое исправление в одну строку без CSS.

{{ myString | limitTo: 20 }}{{myString.length > 20 ? '...' : ''}}

79
Просто и элегантно. Вместо этого '...'вы также можете использовать HTML-сущность для многоточия:'&hellip;'
Том Харрисон

наверное самое безболезненное решение. Помните, что фильтры относительно тяжелые, и это может привести к проблемам с производительностью в огромном списке ng-repeat! :)
Cowwando

1
здорово! Есть ли способ вырезать после нескольких строк, а не после нескольких символов?
Axd

@axd Вы должны попробовать это в css или написать директиву для достижения этой цели.
Гован

1
Это лучший ответ. Падение производительности должно быть незначительным при разумном количестве повторений ng. Если вы возвращаете сотни нг-повторов с контентом, который нужно усечь, то, возможно, придется вернуться к доске для рисования. Хороший ответ, @Govan
erier

59

Я знаю, что уже поздно, но в последней версии angularjs (я использую 1.2.16) фильтр limitTo поддерживает строки, а также массивы, поэтому вы можете ограничить длину строки следующим образом:

{{ "My String Is Too Long" | limitTo: 9 }}

который выведет:

My String

9
В этом решении отсутствует "...". Результат должен быть: «Моя строка ...»
Snæbjørn

Я не вижу здесь многоточия: plnkr.co/edit/HyAejS2DY781bqcT0RgV?p=preview . Можете ли вы уточнить?
похудеть

2
@ Snæbjørn говорит, что тот, кто задал вопрос, предпочел решение, которое вставляет «...» в конце усеченной строки. Ответ Гована делает это.
Nahn

@Нан, спасибо, что указал на это. Я, вероятно, должен был сделать комментарий к ответу EpokK вместо другого ответа.
похудеть

52

Вы можете просто добавить класс css в div и добавить подсказку через angularjs, чтобы обрезанный текст был виден при наведении мыши.

<div class="trim-info" tooltip="{{modal.title}}">{{modal.title}}</div>

   .trim-info {
      max-width: 50px;
      display: inline-block;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;  
      line-height: 15px;
      position: relative;
   }

4
переполнение текста: многоточие, хорошо.
Крис Руссо

4
этот метод, хотя и потрясающий, предотвращает перенос текста
Ларри

Это правильный ответ. Мое общее правило: «Не делай в JavaScript то, что можно сделать в CSS».
помощник

4
Это работает только для текста с одной строкой на абзац. См. Многострочный css-tricks.com/line-clampin (не все браузеры поддерживают это).
Роберт

Это также работает, если вы пытаетесь ограничить длину массива ng-repeat.
Чакеда

27

У меня была похожая проблема, вот что я сделал:

{{ longString | limitTo: 20 }} {{longString.length < 20 ? '' : '...'}}

Я бы удалил пробелы между обоими выходами, чтобы избежать разрыва строки
Игнасио Васкес

21
< div >{{modal.title | limitTo:20}}...< / div>

Самый простой подход, но функциональный. Но предполагается, что каждый заголовок будет иметь более 20 символов, и в некоторых случаях это может быть неожиданным.
Энрике М.

18

Более элегантное решение:

HTML:

<html ng-app="phoneCat">
  <body>
    {{ "AngularJS string limit example" | strLimit: 20 }}
  </body>
</html>

Угловой код:

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

 phoneCat.filter('strLimit', ['$filter', function($filter) {
   return function(input, limit) {
      if (! input) return;
      if (input.length <= limit) {
          return input;
      }

      return $filter('limitTo')(input, limit) + '...';
   };
}]);

Демо-версия:

http://code-chunk.com/chunks/547bfb3f15aa1/str-limit-implementation-for-angularjs


Могу ли я предложить добавить возврат в случае, если inputзначение является динамическим? т.е. в if (!input) {return;}противном случае будут ошибки консоли JS
mcranston18

1
@ mcranston18 добавил. Спасибо.
Анам

15

Поскольку многоточие нам нужно только тогда, когда длина строки превышает предел, представляется целесообразнее добавить многоточие с помощью, а ng-ifне связывания.

{{ longString | limitTo: 20 }}<span ng-if="longString.length > 20">&hellip;</span>

7

Есть вариант

.text {
            max-width: 140px;
            white-space: nowrap;
            overflow: hidden;
            padding: 5px;
            text-overflow: ellipsis;(...)
        }
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi qui soluta labore! Facere nisi aperiam sequi dolores voluptatum delectus vel vero animi, commodi harum molestias deleniti, quasi nesciunt. Distinctio veniam minus ut vero rerum debitis placeat veritatis doloremque laborum optio, nemo quibusdam ad, sed cum quas maxime hic enim sint at quos cupiditate qui eius quam tempora. Ab sint in sunt consequuntur assumenda ratione voluptates dicta dolor aliquid at esse quaerat ea, veritatis reiciendis, labore repellendus rem optio debitis illum! Eos dignissimos, atque possimus, voluptatibus similique error. Perferendis error doloribus harum enim dolorem, suscipit unde vel, totam in quia mollitia.</div>


7

Самое простое решение, которое я нашел для простого ограничения длины строки, было {{ modal.title | slice:0:20 }}, а затем заимствуя у @Govan выше, вы можете использовать, {{ modal.title.length > 20 ? '...' : ''}}чтобы добавить точки подвеса, если строка длиннее 20, поэтому конечный результат просто:

{{ modal.title | slice:0:20 }}{{ modal.title.length > 20 ? '...' : ''}}

https://angular.io/docs/ts/latest/api/common/index/SlicePipe-pipe.html


4

Вот пользовательский фильтр для усечения текста. Он вдохновлен решением EpokK, но изменен для моих потребностей и вкусов.

angular.module('app').filter('truncate', function () {

    return function (content, maxCharacters) {

        if (content == null) return "";

        content = "" + content;

        content = content.trim();

        if (content.length <= maxCharacters) return content;

        content = content.substring(0, maxCharacters);

        var lastSpace = content.lastIndexOf(" ");

        if (lastSpace > -1) content = content.substr(0, lastSpace);

        return content + '...';
    };
});

А вот модульные тесты, чтобы вы могли увидеть, как он должен себя вести:

describe('truncate filter', function () {

    var truncate,
        unfiltered = " one two three four ";

    beforeEach(function () {

        module('app');

        inject(function ($filter) {

            truncate = $filter('truncate');
        });
    });

    it('should be defined', function () {

        expect(truncate).to.be.ok;
    });

    it('should return an object', function () {

        expect(truncate(unfiltered, 0)).to.be.ok;
    });

    it('should remove leading and trailing whitespace', function () {

        expect(truncate(unfiltered, 100)).to.equal("one two three four");
    });

    it('should truncate to length and add an ellipsis', function () {

        expect(truncate(unfiltered, 3)).to.equal("one...");
    });

    it('should round to word boundaries', function () {

        expect(truncate(unfiltered, 10)).to.equal("one two...");
    });

    it('should split a word to avoid returning an empty string', function () {

        expect(truncate(unfiltered, 2)).to.equal("on...");
    });

    it('should tolerate non string inputs', function () {

        expect(truncate(434578932, 4)).to.equal("4345...");
    });

    it('should tolerate falsey inputs', function () {

        expect(truncate(0, 4)).to.equal("0");

        expect(truncate(false, 4)).to.equal("fals...");
    });
});

3

Вы можете ограничить длину строки или массива с помощью фильтра. Проверьте это, написанное командой AngularJS.


также предоставьте более подробную информацию
Parixit

3

В html он используется вместе с фильтром limitTo, предоставляемым самим angular, как показано ниже ,

    <p> {{limitTo:30 | keepDots }} </p>

фильтр keepDots:

     App.filter('keepDots' , keepDots)

       function keepDots() {

        return function(input,scope) {
            if(!input) return;

             if(input.length > 20)
                return input+'...';
            else
                return input;

        }


    }

3

Если вы хотите что-то вроде: InputString => StringPart1 ... StringPart2

HTML:

<html ng-app="myApp">
  <body>
    {{ "AngularJS string limit example" | strLimit: 10 : 20 }}
  </body>
</html>

Угловой код:

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

 myApp.filter('strLimit', ['$filter', function($filter) {
   return function(input, beginlimit, endlimit) {
      if (! input) return;
      if (input.length <= beginlimit + endlimit) {
          return input;
      }

      return $filter('limitTo')(input, beginlimit) + '...' + $filter('limitTo')(input, -endlimit) ;
   };
}]);

Пример со следующими параметрами:
beginLimit = 10
endLimit = 20

До : - /home/house/room/etc/ava_B0363852D549079E3720DF6680E17036.jar
После : - /home/hous...3720DF6680E17036.jar


2
Use this in your html - {{value | limitTocustom:30 }}

and write this custom filter in your angular file,

app.filter('limitTocustom', function() {
    'use strict';
    return function(input, limit) {
        if (input) {
            if (limit > input.length) {
                return input.slice(0, limit);
            } else {
                return input.slice(0, limit) + '...';
            }
        }
    };
});

// if you initiate app name by variable app. eg: var app = angular.module('appname',[])

2

Это может быть не из конца скрипта, но вы можете использовать приведенную ниже CSS и добавить этот класс в div. Это обрезает текст, а также отображает полный текст при наведении курсора. Вы можете добавить больше текста и добавить угловой хедлер, чтобы изменить класс div на cli.

.ellipseContent {
    overflow: hidden;
    white-space: nowrap;
    -ms-text-overflow: ellipsis;
    text-overflow: ellipsis;
}

    .ellipseContent:hover {
        overflow: visible;
        white-space: normal;
    }

2

Если у вас есть две привязки {{item.name}}и {{item.directory}}.

И хотите показать данные в виде каталога, за которым следует имя, принимая в качестве «/ root» в качестве каталога и «Machine» в качестве имени (/ root-machine).

{{[item.directory]+[isLast ? '': '/'] + [ item.name]  | limitTo:5}}

Есть ли шанс, что вы разместили этот ответ на неправильный вопрос? Похоже, это не имеет никакого отношения к ограничению длины строки с AngularJS.
БСМП

1

Вы можете использовать этот модуль npm: https://github.com/sparkalow/angular-truncate

Вставьте усеченный фильтр в модуль приложения следующим образом:

var myApp = angular.module('myApp', ['truncate']); 

и примените фильтр в вашем приложении следующим образом:

{{ text | characters:20 }} 


0

Я создал эту директиву, которая легко это делает, обрезает строку до указанного предела и добавляет переключатель «показать больше / меньше». Вы можете найти его на GitHub: https://github.com/doukasd/AngularJS-Components

это можно использовать так:

<p data-dd-collapse-text="100">{{veryLongText}}</p>

Вот директива:

// a directive to auto-collapse long text
app.directive('ddCollapseText', ['$compile', function($compile) {
return {
    restrict: 'A',
    replace: true,
    link: function(scope, element, attrs) {

        // start collapsed
        scope.collapsed = false;

        // create the function to toggle the collapse
        scope.toggle = function() {
            scope.collapsed = !scope.collapsed;
        };

        // get the value of the dd-collapse-text attribute
        attrs.$observe('ddCollapseText', function(maxLength) {
            // get the contents of the element
            var text = element.text();

            if (text.length > maxLength) {
                // split the text in two parts, the first always showing
                var firstPart = String(text).substring(0, maxLength);
                var secondPart = String(text).substring(maxLength, text.length);

                // create some new html elements to hold the separate info
                var firstSpan = $compile('<span>' + firstPart + '</span>')(scope);
                var secondSpan = $compile('<span ng-if="collapsed">' + secondPart + '</span>')(scope);
                var moreIndicatorSpan = $compile('<span ng-if="!collapsed">...</span>')(scope);
                var toggleButton = $compile('<span class="collapse-text-toggle" ng-click="toggle()">{{collapsed ? "less" : "more"}}</span>')(scope);

                // remove the current contents of the element
                // and add the new ones we created
                element.empty();
                element.append(firstSpan);
                element.append(secondSpan);
                element.append(moreIndicatorSpan);
                element.append(toggleButton);
            }
        });
    }
};
}]);

И немного CSS, чтобы пойти с этим:

.collapse-text-toggle {
font-size: 0.9em;
color: #666666;
cursor: pointer;
}
.collapse-text-toggle:hover {
color: #222222;
}
.collapse-text-toggle:before {
content: '\00a0(';
}
.collapse-text-toggle:after {
content: ')';
}

0

Это решение использует только тег ng в HTML.

Решение состоит в том, чтобы ограничить длинный текст, отображаемый ссылкой «показать больше ...» в конце. Если пользователь щелкнет ссылку «показать больше ...», он покажет остальную часть текста и удалит ссылку «показать больше ...».

HTML:

<div ng-init="limitText=160">
   <p>{{ veryLongText | limitTo: limitText }} 
       <a href="javascript:void(0)" 
           ng-hide="veryLongText.length < limitText" 
           ng-click="limitText = veryLongText.length + 1" > show more..
       </a>
   </p>
</div>

0

Самое простое решение -> я нашел, чтобы позволить Material Design (1.0.0-rc4) сделать работу. md-input-containerБудет делать работу за вас. Он объединяет строку и добавляет elipses, а также имеет дополнительное преимущество, заключающееся в том, что вы можете щелкнуть по нему, чтобы получить полный текст, так что это целая энчилада. Возможно, вам придется установить ширину md-input-container.

HTML:

<md-input-container>
   <md-select id="concat-title" placeholder="{{mytext}}" ng-model="mytext" aria-label="label">
      <md-option ng-selected="mytext" >{{mytext}}
      </md-option>
   </md-select>
</md-input-container>

CS:

#concat-title .md-select-value .md-select-icon{
   display: none; //if you want to show chevron remove this
}
#concat-title .md-select-value{
   border-bottom: none; //if you want to show underline remove this
}

0

Ограничьте количество слов с помощью пользовательского фильтра Angular. Вот как я использовал фильтр Angular, чтобы ограничить количество слов, отображаемых с помощью специального фильтра.

HTML:

<span>{{dataModelObject.TextValue | limitWordsTo: 38}} ......</span>

Угловой / Javascript код

angular.module('app')
.filter('limitWordsTo', function () {
    return function (stringData, numberOfWords) {
        //Get array of words (determined by spaces between words)
        var arrayOfWords = stringData.split(" ");

        //Get loop limit
        var loopLimit = numberOfWords > arrayOfWords.length ? arrayOfWords.length : numberOfWords;

        //Create variables to hold limited word string and array iterator
        var limitedString = '', i;
        //Create limited string bounded by limit passed in
        for (i = 0; i < loopLimit; i++) {
            if (i === 0) {
                limitedString = arrayOfWords[i];
            } else {
                limitedString = limitedString + ' ' + arrayOfWords[i];
            }
        }
        return limitedString;
    }; 
}); //End filter

0

Для меня это нормально работает 'In span', ng-show = "MyCtrl.value. $ ViewValue.length> your_limit" ... читать дальше. 'конец пролета'


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.