Como truncar o texto no Angular2?

126

Existe uma maneira de limitar o comprimento da string a um número de caracteres? por exemplo: eu tenho que limitar o tamanho do título a 20 {{ data.title }}.

Existe algum tubo ou filtro para limitar o comprimento?

ele
fonte

Respostas:

380

Bidirecional para truncar texto em angular.

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

1. Solução

  {{str | slice:0:6}}

Resultado:

   how to

Se você deseja anexar qualquer texto após a sequência de fatias, como

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

Resultado:

 how to...

2. Solução (criar canal personalizado)

se você deseja criar um tubo truncado personalizado

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

Na marcação

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

Não esqueça de adicionar uma entrada de módulo.

@NgModule({
  declarations: [
    TruncatePipe
  ]
})
export class AppModule {}
Ketan Akbari
fonte
Qual solução é boa em desempenho. Solução 1 ou solução 2. Acho que a solução 1 é boa em desempenho.
Rigin Oommen
você pode adicionar uma verificação nula à declaração de retorno. No meu caso, eu estava passando uma string vazia e estava causando o travamento do meu aplicativo. return value && value.length > limit ? value.substring(0, limit) + trail : value;
Wildhammer
@ketan: senhor, eu tentei ambas as soluções, está funcionando perfeitamente, mas meu cenário é diferente. Inicialmente, mostramos 50 caracteres e mais texto será exibido após clique em ler mais link, então me diga o que é possível com acima?
Kapil soni
Na solução 2, transform(value: string, args: string[]): stringdeve ser transform(value: string, args: any[]): stringporque o primeiro argumento dado ao tubo é um número.
MattOnyx 24/02
Olá Ketan, você pode responder a esta: stackoverflow.com/questions/61040964/…
Tanzeel
83

Truncar tubulação com parâmetros opcionais :

  • limit - comprimento máximo da string
  • completeWords - Sinalize para truncar na palavra completa mais próxima, em vez do caractere
  • reticências - sufixo à direita anexado

-

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

Não esqueça de adicionar uma entrada de módulo.

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

Uso

Sequência de exemplo:

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

Marcação:

  <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*** -->
Timothy Perez
fonte
7
Obrigado por fornecer um tubo, limit = value.substr(0, 13).lastIndexOf(' ');deve ser limit = value.substr(0, limit).lastIndexOf(' ');embora.
Tomnar 4/09/18
1
Você também pode adicionar algo assim: if (!value) { return ''; }e if (value.length <= limit) { return value; }
Jarek Szczepański
Eu tive que adicioná-lo à parte de exportação do @ngModule também para fazê-lo funcionar. não sei porquê
tibi
@tibi é como um novo componente e você precisa declará-lo (array de declarações) para usá-lo.
calios 17/02/19
1
Para evitar evitar acrescentar reticências a valores desnecessários, adicione use `if (value.length <limit) {return value; } else {return ${value.substr(0, limit)}${ellipsis}; } `
jabu.hlong 18/04/19
13

Você pode truncar o texto com base em CSS. Isso ajuda a truncar um caractere com base na largura e não na correção de texto.

Exemplo

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>

Nota: este código é usado completo para uma linha e não para mais de uma.

A solução da Ketan é melhor se você quiser fazê-lo pela Angular

Shailesh Ladumor
fonte
2
Este. Mil vezes isso!
Brunner
perfeito para acessibilidade
Antonello Pasella 14/04
4

Eu tenho usado este módulo ng2 truncado , é muito fácil, módulo de importação e você está pronto para ir ... in {{data.title | truncar: 20}}

Kerim092
fonte
meus testes falharam depois de importar isso. Jest teve alguns erros com fio.
Tibi
@tibi que tipo de erros? para mim foi muito simples, instalar> importação no módulo> uso em seus componentes ..
Kerim092
3

Aqui está uma abordagem alternativa usando um interfacepara descrever a forma de um objeto de opções a ser passado por meio pipeda marcação.

@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;
}

Em seguida, na sua marcação:

{{someText | textContentTruncate:{sliceStart: 0, sliceEnd: 50, append: '...'} }}
cssimsek
fonte
2

Muito simples usando o tubo de fatia (tubo de núcleo da angular), como você pediu data.title:

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

Dos documentos comuns do Angular https://angular.io/api/common/SlicePipe

Ignacio Ara
fonte
1

Se você deseja truncar por várias palavras e adicionar reticências, pode usar esta função:

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

Exemplo:

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

extraído de: https://github.com/yellowspot/ng2-truncate/blob/master/src/truncate-words.pipe.ts

Se você deseja truncar por um número de letras, mas não recortar palavras, use o seguinte:

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}`;
}

Exemplo:

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…"
Gianfranco P.
fonte
1

Tentei a resposta @ Timothy Perez e adicionei uma linha

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

para

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}`;
}
}
unos baghaii
fonte
0

Experimente este, se você deseja truncar com base em Palavras, em vez de caracteres, enquanto também permite uma opção para ver o texto completo.

Vi aqui procurando uma solução Leia Mais baseada em palavras , compartilhando o costumePipe que acabei escrevendo.

Tubo:

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

}

No modelo:

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

Componente:

export class ExamplePage implements OnInit {

    public showAll: any = false;

    triggerReadMore() {
        this.showAll = true;
    }

}

No módulo:

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

@NgModule({
  declarations: [ReadMorePipe]
})
export class ExamplePageModule {}
shazyriver
fonte