Il tubo "" non è stato trovato tubo personalizzato angolare2


105

Non riesco a correggere questo errore. Ho una barra di ricerca e un file ngFor. Sto cercando di filtrare l'array utilizzando una pipe personalizzata come questa:

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

import { User } from '../user/user';

@Pipe({
  name: 'usersPipe',
  pure: false
})
export class UsersPipe implements PipeTransform {
  transform(users: User [], searchTerm: string) {
    return users.filter(user => user.name.indexOf(searchTerm) !== -1);
  }
}

Uso:

<input [(ngModel)]="searchTerm" type="text" placeholder="Search users">

<div *ngFor="let user of (users | usersPipe:searchTerm)">
...
</div>

Errore:

zone.js:478 Unhandled Promise rejection: Template parse errors:
The pipe 'usersPipe' could not be found ("
<div class="row">
    <div  
    [ERROR ->]*ngFor="let user of (user | usersPipe:searchTerm)">

Versioni angolari:

"@angular/common": "2.0.0-rc.5",
"@angular/compiler": "2.0.0-rc.5",
"@angular/core": "2.0.0-rc.5",
"@angular/platform-browser": "2.0.0-rc.5",
"@angular/platform-browser-dynamic": "2.0.0-rc.5",
"@angular/router": "3.0.0-rc.1",
"@angular/forms": "0.3.0",
"@angular/http": "2.0.0-rc.5",
"es6-shim": "^0.35.0",
"reflect-metadata": "0.1.3",
"rxjs": "5.0.0-beta.6",
"systemjs": "0.19.26",
"bootstrap": "^3.3.6",
"zone.js": "^0.6.12"

1
Lo hai incluso nei tubi dei componenti?
Harry Ninh

Ho appena capito che era questo il motivo. Come mai l'esempio angolare per pipe personalizzate non fa mai questo: angular.io/resources/live-examples/pipes/ts/plnkr.html
Sumama Waheed

Lo hanno definito come global pipe. Puoi fare lo stesso con la tua pipe personalizzata se la usi in molti posti e non vuoi definire in ogni singola annotazione.
Harry Ninh

@ SumamaWaheed Sono abbastanza sicuro che fosse lì a un certo punto nei documenti, ma hai ragione, i documenti ora non lo menzionano / lo mostrano.
Michelangelo

Risposte:


144

Assicurati di non affrontare un problema di "modulo incrociato"

Se il componente che utilizza la pipe, non appartiene al modulo che ha dichiarato il componente pipe "globalmente", la pipe non viene trovata e viene visualizzato questo messaggio di errore.

Nel mio caso ho dichiarato la pipe in un modulo separato e ho importato questo modulo pipe in qualsiasi altro modulo avente componenti che utilizzano la pipe.

Ho dichiarato a che il componente in cui stai usando il tubo è

il modulo tubi

 import { NgModule }      from '@angular/core';
 import { myDateFormat }          from '../directives/myDateFormat';

 @NgModule({
     imports:        [],
     declarations:   [myDateFormat],
     exports:        [myDateFormat],
 })

 export class PipeModule {

   static forRoot() {
      return {
          ngModule: PipeModule,
          providers: [],
      };
   }
 } 

Utilizzo in un altro modulo (ad es. App.module)

  // Import APPLICATION MODULES
  ...
  import { PipeModule }    from './tools/PipeModule';

  @NgModule({
     imports: [
    ...
    , PipeModule.forRoot()
    ....
  ],

6
Questa soluzione è stata l'unica che ha funzionato per me. Risulta che i tubi devono avere un modulo
AJ Zane

Anch'io ho trovato questo per risolvere parzialmente il mio errore di pipe non trovato in Ng 2.8. * Inoltre, avevo "avvisi" dattiloscritti relativi solo alle convenzioni di denominazione in uso, che dopo averle risolte, hanno contribuito a questa pipa personalizzata che transpiling correttamente e alla fine è stata trovata nel modello.
CNSKnight

Questa è davvero l'unica soluzione che ha funzionato per me! Ho provato l'intera cosa del modulo condiviso, ma questa soluzione ha funzionato a meraviglia. Grazie @Karl!
lulu88

come lo
testiamo

2
Grazie! Il mio problema era che mi mancava "export: [myPipe]" pensando che le esportazioni fossero solo per i moduli!
Rafique Mohammed

55

Devi includere la tua pipe nella dichiarazione del modulo:

declarations: [ UsersPipe ],
providers: [UsersPipe]

5
Solo una nota, originariamente ho incluso solo la pipa nei provider. Questo deve essere incluso sia nelle dichiarazioni che nei provider nel file del modulo.
Greg A

Stavo lottando finché non ho seguito il tuo suggerimento. Ho sprecato circa 4 ore per capirlo. Grazie per il suggerimento.
user1501382

5
Perché non è documentato? La documentazione afferma You must include your pipe in the declarations array of the AppModule.: angular.io/guide/pipes . Ad ogni modo, la tua risposta risolve anche il mio problema.
Martijn

Grazie, Yuvals. Aggiungo un dettaglio: dichiarazione del modulo dove serve la pipa.
Vinicios Torres

5
Non dimenticare di includere anche exports: [UsersPipe]se il modulo verrà importato da altri moduli.
Precastica

18

Per Ionic puoi affrontare più problemi come menzionato da @Karl. La soluzione che funziona perfettamente per le pagine ioniche caricate pigre è:

  1. Crea la directory delle pipe con i seguenti file: pipe.ts e pipe.module.ts

// contenuto di pipe.ts (può avere più pipe all'interno, ricordati di farlo

use @Pipe function before each class)
import { PipeTransform, Pipe } from "@angular/core";
@Pipe({ name: "toArray" })
export class toArrayPipe implements PipeTransform {
  transform(value, args: string[]): any {
    if (!value) return value;
    let keys = [];
    for (let key in value) {
      keys.push({ key: key, value: value[key] });
    }
    return keys;
  }
}

// contenuto di pipe.module.ts

import { NgModule } from "@angular/core";
import { IonicModule } from "ionic-angular";
import { toArrayPipe } from "./pipes";

@NgModule({
  declarations: [toArrayPipe],
  imports: [IonicModule],
  exports: [toArrayPipe]
})
export class PipesModule {}
  1. Includere PipesModule nella sezione delle importazioni di app.module e @NgModule

    import { PipesModule } from "../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] });

  2. Includi PipesModule in ciascuno dei tuoi .module.ts in cui desideri utilizzare pipe personalizzate. Non dimenticare di aggiungerlo nella sezione delle importazioni. // Esempio. file: pages / my-custom-page / my-custom-page.module.ts

    import { PipesModule } from "../../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] })

  3. Questo è tutto. Ora puoi usare la tua pipe personalizzata nel tuo modello. Ex.

<div *ngFor="let prop of myObject | toArray">{{ prop.key }}</div>


Questo è stato un vero toccasana per ionico, grazie. Perché "ionic generate pipe ...." non genera tutti i passaggi necessari, come la creazione di pipe.module.ts. Il tuo approccio ha funzionato perfettamente. Nota, per ionic v4, sono necessarie alcune piccole modifiche ai percorsi di importazione.
royappa

1
Ho scoperto che non hai bisogno delle importazioni in app.module.ts, quindi quel passaggio può essere omesso. Deve essere perché il "modulo condiviso" viene comunque importato in ogni altro modulo dove è necessario. Sarebbe bello se l'importazione di app.module funzionasse a livello globale, ma ho provato e non funziona.
royappa

Sto ancora affrontando questo: CONSOLE ERROR file: node_modules/@angular/core/fesm5/core.js: 4002: 0 ERROR Error: Uncaught (in promise): NullInjectorError: StaticInjectorError (AppModule) [ToHtmlPipe -> DomSanitizer]: StaticInjectorError (Piattaforma: core) [ToHtmlPipe -> DomSanitizer]: NullInjectorError: Nessun provider per DomSanitizer!
mircobabini

12

Ho trovato la risposta "modulo incrociato" sopra molto utile per la mia situazione, ma vorrei approfondire questo aspetto, poiché c'è un altro aspetto da considerare. Se hai un sottomodulo, anche nei miei test non può vedere i tubi nel modulo genitore. Anche per questo motivo, potrebbe essere necessario inserire i tubi in un modulo separato.

Ecco un riepilogo dei passaggi che ho seguito per affrontare i tubi non visibili nel sottomodulo:

  1. Estrarre i tubi da (genitore) SharedModule e inserirli in PipeModule
  2. In SharedModule, importa PipeModule ed esporta (per altre parti dell'app dipendenti da SharedModule per ottenere automaticamente l'accesso a PipeModule)
  3. Per Sub-SharedModule, importa PipeModule, in modo che possa accedere a PipeModule, senza dover reimportare SharedModule che creerebbe un problema di dipendenza circolare, tra gli altri problemi.

Un'altra nota a piè di pagina alla risposta "cross module" sopra: quando ho creato il PipeModule ho rimosso il metodo statico forRoot e ho importato PipeModule senza quello nel mio modulo condiviso. La mia comprensione di base è che forRoot è utile per scenari come i singleton, che non si applicano necessariamente ai filtri.


1
Grazie per aver aggiunto questo. Ha funzionato per me solo una volta che è stato aggiunto a Sub-SharedModule
jmcgrath207

Sì lo stesso qui, la parte che mi mancava era l'importazione di PipesModule nel Sub-SharedModule.
filetto

1

Suggerendo una risposta alternativa qui:

Realizzando un modulo separato per il tubo non è necessaria , ma è decisamente un'alternativa. Controlla la nota a piè di pagina dei documenti ufficiali: https://angular.io/guide/pipes#custom-pipes

Utilizzi il tuo tubo personalizzato nello stesso modo in cui usi i tubi incorporati.
È necessario includere la pipa nella matrice delle dichiarazioni di AppModule. Se scegli di iniettare la tua pipe in una classe, devi fornirla nell'array dei provider del tuo NgModule.

Tutto quello che devi fare è aggiungere la tua pipe all'array delle dichiarazioni e l' array dei provider nel punto in modulecui vuoi usare il Pipe.

declarations: [
...
CustomPipe,
...
],
providers: [
...
CustomPipe,
...
]

Ma un singolo tubo non può essere una parte di 2 moduli .... L'approccio sopra lo rende più accessibile in diversi moduli.
Himanshu Bansal,

0

Nota : solo se non si utilizzano moduli angolari

Per qualche motivo questo non è nei documenti, ma ho dovuto importare la pipe personalizzata nel componente

import {UsersPipe} from './users-filter.pipe'

@Component({
    ...
    pipes:      [UsersPipe]
})

1
Nel Plunker che hai pubblicato sopra, i tubi vengono importati nel modulo dell'app (esattamente come fai con i componenti stessi), il che rende il tubo disponibile per tutti i componenti in quel modulo.
ABabin

Oh ok, stavo effettivamente guardando il componente che utilizza effettivamente il tubo personalizzato. Non sapevo che potesse essere importato globalmente nel modulo dell'app. Grazie
Sumama Waheed

utenti-filter.pipe? perché .pipe?
Nather Webber

1
Questa è solo una convenzione di denominazione, il file si chiama users-filter.pipe.ts
Sumama Waheed

2
@SachinThampan potrebbe essere perché questo era quando angular era in rc5 penso ... le cose sono cambiate da allora specialmente con NgModule. Si prega di guardare i documenti per NgModule
Sumama Waheed

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

@Pipe({
  name: 'timePipe'
})
export class TimeValuePipe implements PipeTransform {

  transform(value: any, args?: any): any {
   var hoursMinutes = value.split(/[.:]/);
  var hours = parseInt(hoursMinutes[0], 10);
  var minutes = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
  console.log('hours ', hours);
  console.log('minutes ', minutes/60);
  return (hours + minutes / 60).toFixed(2);
  }
}
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular';
  order = [
    {
      "order_status": "Still at Shop",
      "order_id": "0:02"
    },
    {
      "order_status": "On the way",
      "order_id": "02:29"
    },
    {
      "order_status": "Delivered",
      "order_id": "16:14"
    },
     {
      "order_status": "Delivered",
      "order_id": "07:30"
    }
  ]
}

Invoke this module in App.Module.ts file.

-2

Ho creato un modulo per pipe nella stessa directory in cui sono presenti le mie pipe

import { NgModule } from '@angular/core';
///import pipe...
import { Base64ToImage, TruncateString} from './'  

   @NgModule({
        imports: [],
        declarations: [Base64ToImage, TruncateString],
        exports: [Base64ToImage, TruncateString]
    })

    export class SharedPipeModule { }   

Ora importa quel modulo in app.module:

import {SharedPipeModule} from './pipe/shared.pipe.module'
 @NgModule({
     imports: [
    ...
    , PipeModule.forRoot()
    ....
  ],

Ora può essere utilizzato importando lo stesso nel modulo annidato

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.