Html:

<div class="box" *ngFor="let game of gameData | gameFilter: searchText | slice:1; let i = index">

Tubo:

export class GameFilterPipe implements PipeTransform {

  transform(items: any, searchText: string): any[] {
    if (!items) {
      return [];
    }
    if (!searchText) {
      return items;
    }
    searchText = searchText.toLowerCase();

    let timeout;
    if (timeout) { clearTimeout(timeout); }
    timeout = setTimeout(() => {
      performSearch(searchText);
    }, 2000);

    function performSearch(txt) {
      if (txt.length < 5) { return; }
      const filtered = items.filter((e: any, i: number) => {
        if (i > 0) {
          return e.title.toLowerCase().includes(txt);
        }
      });
      console.log('filtered ', filtered); // logs data after change
      return filtered;
    }
  }
}

Veo los datos registrados después del filtro, pero la interfaz de usuario no se actualiza. Intenté ambos pure and impure pero aún no funciona.

Tengo datos registrados de esta manera:

(3) [{…}, {…}, {…}]
0: {title: "LittleBigPlanet PS Vita", platform: "PlayStation Vita", score: 9, genre: "Platformer", editors_choice: "Y"}
1: {title: "LittleBigPlanet PS Vita -- Marvel Super Hero Edition", platform: "PlayStation Vita", score: 9, genre: "Platformer", editors_choice: "Y"}
2: {title: "New Little King's Story", platform: "PlayStation Vita", score: 5.8, genre: "RPG", editors_choice: "N"}
length: 3
__proto__: Array(0)
-1
kittu 24 jun. 2020 a las 20:31

3 respuestas

La mejor respuesta

Su pipa no está devolviendo nada. Su función interna performSearch parece que realiza una búsqueda, pero si la envuelve dentro de un setTimeout() hace que su tubería regrese indefinida.

Aquí hay una prueba que lo demuestra.

No está claro por qué está utilizando setTimeout(), por lo que le recomiendo eliminarlo.

  transform(items: any, searchText: string): any[] {
    if (!items) {
      return [];
    }
    if (!searchText) {
      return items;
    }
    const txt = searchText.toLowerCase();
    if (txt.length < 5) { return; }
    const filtered = items.filter((e: any, i: number) => {
      return e.title.toLowerCase().includes(txt);
    });
    console.log('filtered ', filtered);
    return filtered;
  }
1
spots 24 jun. 2020 a las 18:13

Intenta devolver el resultado de la función también

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'gameFilter'
})
export class GameFilterPipe implements PipeTransform {
  transform(items: any, searchText: string): any[] {
    if (!items) {return [];}
    if (!searchText || searchText.length < 5) { return items; }
    searchText = searchText.toLowerCase();
    return performSearch(searchText);
    function performSearch(txt) {
      return  items.filter((e: any, i: number) => {
        if (i > 0) { return e.title.toLowerCase().indexOf(txt)>-1; }
      });
    }
  }
}

Esperar no es una buena opción porque bloqueará el valor de entrada durante 2 segundos como congelación, pero si lo desea, hágalo como

    function wait(ms){
      var start = new Date().getTime();
      var end = start;
      while(end < start + ms) { end = new Date().getTime(); }
    }
    wait(2000);
    return performSearch(searchText);
0
pc_coder 24 jun. 2020 a las 19:17

Su función performSearch devuelve el resultado filtrado, pero su canalización no lo hace.

Entonces, tienes que devolver el resultado también

timeout = setTimeout(() => {
    return performSearch(searchText);
}, 2000);
0
Sergiu Molnar 24 jun. 2020 a las 17:59