¿Cómo truncar texto en Angular2?

126

¿Hay alguna forma de limitar la longitud de la cadena a un número de caracteres? por ejemplo: tengo que limitar la longitud de un título a 20 {{ data.title }}.

¿Hay alguna tubería o filtro para limitar la longitud?

él
fuente

Respuestas:

380

Dos formas de truncar el texto en angular.

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

1. Solución

  {{str | slice:0:6}}

Salida:

   how to

Si desea agregar texto después de la cadena de corte como

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

Salida:

 how to...

2. Solución (crear tubería personalizada)

si desea crear una tubería truncada personalizada

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

En marcado

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

No olvide agregar una entrada de módulo.

@NgModule({
  declarations: [
    TruncatePipe
  ]
})
export class AppModule {}
Ketan Akbari
fuente
Qué solución tiene un buen rendimiento. Solución 1 o solución 2. Creo que la solución 1 tiene un buen rendimiento.
Rigin Oommen
es posible que desee agregar un cheque nulo a la declaración de devolución, en mi caso, estaba pasando una cadena vacía y estaba causando que mi aplicación fallara. return value && value.length > limit ? value.substring(0, limit) + trail : value;
Wildhammer
@ketan: señor, he probado ambas soluciones, funcionan perfectamente, pero mi escenario es diferente, inicialmente mostramos 50 caracteres y se mostrará más texto después de hacer clic en leer más enlace, así que dime si es posible con lo anterior.
Kapil soni
En la solución 2, transform(value: string, args: string[]): stringdebería ser transform(value: string, args: any[]): stringya que el primer argumento dado a la tubería es un número.
MattOnyx
Hola Ketan, puede usted por favor responder a esta: stackoverflow.com/questions/61040964/...
Tanzeel
83

Truncar tubería con parámetros opcionales :

  • límite - longitud máxima de la cuerda
  • completeWords : marca para truncar en la palabra completa más cercana, en lugar de carácter
  • puntos suspensivos - sufijo final añadido

-

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

No olvide agregar una entrada de módulo.

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

Uso

Cadena de ejemplo:

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

Margen:

  <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
fuente
7
Gracias por proporcionar una pipa, limit = value.substr(0, 13).lastIndexOf(' ');debería serlo limit = value.substr(0, limit).lastIndexOf(' ');.
Tomnar
1
También puede agregar algo como eso: if (!value) { return ''; }y if (value.length <= limit) { return value; }
Jarek Szczepański
Tuve que agregarlo a la parte de exportación de @ngModule también para que funcione. no estoy seguro de por qué
tibi
@tibi es como un nuevo componente y necesita declararlo (matriz de declaraciones) para poder usarlo.
Calios
1
Para evitar añadir puntos suspensivos a valores innecesarios, agregue el uso de `if (value.length <limit) {return value; } else {volver ${value.substr(0, limit)}${ellipsis}; } `
jabu.hlong
15

Puede truncar texto basado en CSS. Ayuda a truncar un texto basado en el ancho, no en un carácter fijo.

Ejemplo

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 se usa completo para una línea, no para más de una.

La solución de Ketan es la mejor si quieres hacerlo por Angular

Shailesh Ladumor
fuente
2
Esta. ¡Mil veces esto!
brunner
perfecto para la accesibilidad
Antonello Pasella
4

He estado usando este módulo ng2 truncate , es bastante fácil, importa el módulo y estás listo para comenzar ... en {{data.title | truncar: 20}}

Kerim092
fuente
mis pruebas fallaron después de importar esto. broma tuvo algunos errores de cableado.
tibi
@tibi ¿qué tipo de errores? para mi fue muy simple, instalar> importar en módulo> usar en sus componentes ..
Kerim092
3

Aquí hay un enfoque alternativo que usa un interfacepara describir la forma de un objeto de opciones que se pasará a través del pipeen el marcado.

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

Luego, en tu marcado:

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

Muy simple usando la tubería de corte (tubería central de angular), como solicitó data.title:

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

De los documentos comunes de Angular https://angular.io/api/common/SlicePipe

Ignacio Ara
fuente
1

Si desea truncar por varias palabras y agregar puntos suspensivos, puede usar esta función:

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

Ejemplo:

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

Si desea truncar por varias letras pero no corte palabras, use esto:

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

Ejemplo:

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.
fuente
1

Acabo de probar la respuesta de @Timothy Perez y agregué una línea

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

a

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
fuente
0

Pruebe este, si desea truncar basándose en palabras en lugar de caracteres y al mismo tiempo permitir una opción para ver el texto completo.

Vine aquí buscando una solución Leer más basada en palabras , compartiendo la costumbre que Pipeterminé escribiendo.

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

}

En plantilla:

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

}

En módulo:

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

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