Как обрезать текст в Angular2?

127

Есть ли способ ограничить длину строки числовыми символами? например: я должен ограничить длину заголовка до 20 {{ data.title }}.

Есть ли труба или фильтр для ограничения длины?

ему
источник

Ответы:

380

Два способа усечь текст до углового.

let str = 'How to truncate text in angular';

1. Решение

  {{str | slice:0:6}}

Вывод:

   how to

Если вы хотите добавить любой текст после строки среза, например

   {{ (str.length>6)? (str | slice:0:6)+'..':(str) }}

Вывод:

 how to...

2. Решение (создать собственный канал)

если вы хотите создать собственный канал усечения

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
 name: 'truncate'
})

export class TruncatePipe implements PipeTransform {

transform(value: string, args: any[]): string {
    const limit = args.length > 0 ? parseInt(args[0], 10) : 20;
    const trail = args.length > 1 ? args[1] : '...';
    return value.length > limit ? value.substring(0, limit) + trail : value;
   }
}

В разметке

{{ str | truncate:[20] }} // or 
{{ str | truncate:[20, '...'] }} // or

Не забудьте добавить запись модуля.

@NgModule({
  declarations: [
    TruncatePipe
  ]
})
export class AppModule {}
Кетан Акбари
источник
Какое решение хорошее по производительности. Решение 1 или решение 2. Я считаю, что решение 1 имеет хорошую производительность.
Rigin Oommen
вы могли бы захотеть добавить нулевую проверку к оператору return, в моем случае я передавал пустую строку, и это приводило к сбою моего приложения. return value && value.length > limit ? value.substring(0, limit) + trail : value;
Wildhammer
@ketan: сэр, я попробовал оба решения, которые работают отлично, но мой сценарий отличается, у нас изначально отображается 50 символов, и после щелчка по ссылке «Читать дальше» будет отображаться больше текста, поэтому скажите мне, что это возможно с помощью выше?
Kapil soni
В решении 2 transform(value: string, args: string[]): stringдолжно быть, transform(value: string, args: any[]): stringпоскольку первым аргументом, передаваемым каналу, является число.
MattOnyx
Привет, Кетан, не могли бы вы ответить на это: stackoverflow.com/questions/61040964/…
Танзил
83

Усечь трубу с дополнительным параметрами:

  • предел - максимальная длина строки
  • completeWords - пометка для усечения до ближайшего полного слова вместо символа
  • многоточие - добавляемый конечный суффикс

-

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'truncate'
})
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit = 25, completeWords = false, ellipsis = '...') {
    if (completeWords) {
      limit = value.substr(0, limit).lastIndexOf(' ');
    }
    return value.length > limit ? value.substr(0, limit) + ellipsis : value;
  }
}

Не забудьте добавить запись модуля.

@NgModule({
  declarations: [
    TruncatePipe
  ]
})
export class AppModule {}

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

Пример строки:

public longStr = 'A really long string that needs to be truncated';

Разметка:

  <h1>{{longStr | truncate }}</h1> 
  <!-- Outputs: A really long string that... -->

  <h1>{{longStr | truncate : 12 }}</h1> 
  <!-- Outputs: A really lon... -->

  <h1>{{longStr | truncate : 12 : true }}</h1> 
  <!-- Outputs: A really... -->

  <h1>{{longStr | truncate : 12 : false : '***' }}</h1> 
  <!-- Outputs: A really lon*** -->
Тимоти Перес
источник
7
Спасибо за трубку, limit = value.substr(0, 13).lastIndexOf(' ');должно быть limit = value.substr(0, limit).lastIndexOf(' ');.
Tomnar
1
Вы также можете добавить что-то вроде этого: if (!value) { return ''; }и if (value.length <= limit) { return value; }
Jarek Szczepański
Мне пришлось добавить его в экспортную часть @ngModule, чтобы он заработал. Не уверен, почему
tibi
@tibi - это как новый компонент, и вам нужно объявить (массив объявлений) его, чтобы использовать.
Калиос,
1
Чтобы избежать добавления многоточия к ненужным значениям, добавьте use `if (value.length <limit) {return value; } else {return ${value.substr(0, limit)}${ellipsis}; } `
jabu.hlong
16

Вы можете обрезать текст на основе CSS. Это помогает обрезать текст на основе ширины, а не фиксированного символа.

пример

CSS

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

.content {
            width:100%;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

HTML

<div class="content">
    <span class="truncate">Lorem Ipsum is simply dummied text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</span>
</div>

Примечание: этот код используется для одной строки, а не более чем для одной.

Решение Ketan лучше всего, если вы хотите сделать это с помощью Angular

Шайлеш Ладумор
источник
2
Это. В тысячу раз больше!
Brunner
идеально подходит для доступности
Антонелло Паселла
4

Я использовал этот модуль ng2 truncate , его довольно простой модуль импорта, и вы готовы к работе ... в {{data.title | truncate: 20}}

Kerim092
источник
он перемещен сюда: npmjs.com/package/@yellowspot/ng-truncate
tibi
мои тесты не удались после импорта этого. У jest были некоторые проводные ошибки.
tibi
@tibi какие ошибки? для меня это было очень просто: установить> импортировать в модуль> использовать в его компонентах ..
Kerim092 03
3

Вот альтернативный подход, использующий interfaceдля описания формы объекта параметров, передаваемого через pipeв разметке.

@Pipe({
  name: 'textContentTruncate'
})
export class TextContentTruncatePipe implements PipeTransform {

  transform(textContent: string, options: TextTruncateOptions): string {
    if (textContent.length >= options.sliceEnd) {
      let truncatedText = textContent.slice(options.sliceStart, options.sliceEnd);
      if (options.prepend) { truncatedText = `${options.prepend}${truncatedText}`; }
      if (options.append) { truncatedText = `${truncatedText}${options.append}`; }
      return truncatedText;
    }
    return textContent;
  }

}

interface TextTruncateOptions {
  sliceStart: number;
  sliceEnd: number;
  prepend?: string;
  append?: string;
}

Затем в вашей разметке:

{{someText | textContentTruncate:{sliceStart: 0, sliceEnd: 50, append: '...'} }}
cssimsek
источник
2

Очень просто использовать slice pipe (основная труба angular), как вы просили data.title:

{{ data.title | slice:0:20 }}

Из общих документов Angular https://angular.io/api/common/SlicePipe

Игнасио Ара
источник
1

Если вы хотите усечь на несколько слов и добавить многоточие, вы можете использовать эту функцию:

truncate(value: string, limit: number = 40, trail: String = '…'): string {
  let result = value || '';

  if (value) {
    const words = value.split(/\s+/);
    if (words.length > Math.abs(limit)) {
      if (limit < 0) {
        limit *= -1;
        result = trail + words.slice(words.length - limit, words.length).join(' ');
      } else {
        result = words.slice(0, limit).join(' ') + trail;
      }
    }
  }

  return result;
}

Пример:

truncate('Bacon ipsum dolor amet sirloin tri-tip swine', 5, '…')
> "Bacon ipsum dolor amet sirloin…"

взято из: https://github.com/yellowspot/ng2-truncate/blob/master/src/truncate-words.pipe.ts

Если вы хотите обрезать по количеству букв, но не вырезать слова, используйте это:

truncate(value: string, limit = 25, completeWords = true, ellipsis = '…') {
  let lastindex = limit;
  if (completeWords) {
    lastindex = value.substr(0, limit).lastIndexOf(' ');
  }
  return `${value.substr(0, limit)}${ellipsis}`;
}

Пример:

truncate('Bacon ipsum dolor amet sirloin tri-tip swine', 19, true, '…')
> "Bacon ipsum dolor…"

truncate('Bacon ipsum dolor amet sirloin tri-tip swine', 19, false, '…')
> "Bacon ipsum dolor a…"
Джанфранко П.
источник
1

Просто попробовал ответить @Timothy Perez и добавил строку

if (value.length < limit)
   return `${value.substr(0, limit)}`;

в

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'truncate'
})
export class TruncatePipe implements PipeTransform {
transform(value: string, limit = 25, completeWords = false, ellipsis = '...') {

   if (value.length < limit)
   return `${value.substr(0, limit)}`;

   if (completeWords) {
     limit = value.substr(0, limit).lastIndexOf(' ');
   }
   return `${value.substr(0, limit)}${ellipsis}`;
}
}
Унос Багхай
источник
0

Попробуйте это, если вы хотите обрезать на основе слов, а не символов, при этом также позволяя видеть полный текст.

Пришел сюда в поисках решения Read More, основанного на словах , поделившись тем, что Pipeя написал.

Труба:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'readMore'
})
export class ReadMorePipe implements PipeTransform {

  transform(text: any, length: number = 20, showAll: boolean = false, suffix: string = '...'): any {

    if (showAll) {
      return text;
    }

    if ( text.split(" ").length > length ) {

      return text.split(" ").splice(0, length).join(" ") + suffix;
    }

    return text;
  }

}

В шаблоне:

<p [innerHTML]="description | readMore:30:showAll"></p>
<button (click)="triggerReadMore()" *ngIf="!showAll">Read More<button>

Составная часть:

export class ExamplePage implements OnInit {

    public showAll: any = false;

    triggerReadMore() {
        this.showAll = true;
    }

}

В модуле:

import { ReadMorePipe } from '../_helpers/read-more.pipe';

@NgModule({
  declarations: [ReadMorePipe]
})
export class ExamplePageModule {}
shazyriver
источник