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

225

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

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

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

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

alan2
источник
3
jsfiddle.net/tUyyx
Ufuk Hacıoğulları

Ответы:

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)

EpokK
источник
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 ? '...' : ''}}
Govan
источник
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;
   }
Sushrut
источник
4
переполнение текста: многоточие, хорошо.
Крис Руссо
4
этот метод, хотя и потрясающий, предотвращает перенос текста
Ларри
Это правильный ответ. Мое общее правило: «Не делай в JavaScript то, что можно сделать в CSS».
помощник
4
Это работает только для текста с одной строкой на абзац. См. Многострочный css-tricks.com/line-clampin (не все браузеры поддерживают это).
Роберт
Это также работает, если вы пытаетесь ограничить длину массива ng-repeat.
Чакеда
27

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

{{ longString | limitTo: 20 }} {{longString.length < 20 ? '' : '...'}}
crc442
источник
Я бы удалил пробелы между обоими выходами, чтобы избежать разрыва строки
Игнасио Васкес
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>
mnishiguchi
источник
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

maudulus
источник
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...");
    });
});
SharkAlley
источник
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

vhamon
источник
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;
    }
Kurkula
источник
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>
Amirul
источник
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
}
Helzgate
источник
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
Geoff
источник
0

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

Г.К.
источник
0

Я использую хороший набор полезных библиотек фильтров "Angular-filter", и одна из них называется "truncate".

https://github.com/a8m/angular-filter#truncate

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

text | truncate: [length]: [suffix]: [preserve-boolean]
Лукас Елинек
источник