web-dev-qa-db-fra.com

Le tuyau '' n'a pas pu être trouvé tuyau personnalisé angular2

Je n'arrive pas à corriger cette erreur. J'ai une barre de recherche et un ngFor. J'essaie de filtrer le tableau en utilisant un tuyau personnalisé comme ceci:

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

Usage:

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

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

Erreur:

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)">

Versions angulaires:

"@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"
79
Sumama Waheed

Assurez-vous de ne pas rencontrer un problème de "module croisé"

Si le composant qui utilise le tuyau n'appartient pas au module qui a déclaré le composant de tuyau "globalement", le tuyau n'est pas trouvé et vous obtenez ce message d'erreur.

Dans mon cas, j'ai déclaré le tuyau dans un module séparé et importé ce module de tuyau dans tout autre module ayant des composants utilisant le tuyau.

J'ai déclaré un Que le composant dans lequel vous utilisez le tuyau est 

le module de tuyauterie

 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: [],
      };
   }
 } 

Utilisation dans un autre module (par exemple, app.module)

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

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

Vous devez inclure votre pipe dans la déclaration du module: 

declarations: [ UsersPipe ],
providers: [UsersPipe]
45
Yuvals

J'ai trouvé la réponse "module croisé" ci-dessus très utile à ma situation, mais je voudrais développer cela, car il y a un autre problème à considérer. Si vous avez un sous-module, il ne peut pas non plus voir les tuyaux dans le module parent lors de mes tests. Pour cette raison également, vous devrez peut-être insérer des tuyaux dans leur propre module séparé. 

Voici un résumé des étapes que j'ai prises pour éliminer les tuyaux non visibles dans le sous-module:

  1. Sortez les tuyaux de SharedModule (parent) et mettez-les dans PipeModule
  2. Dans SharedModule, importez PipeModule et exportez (pour les autres parties de l'app dépendant de SharedModule pour accéder automatiquement à PipeModule)
  3. Pour Sub-SharedModule, importez PipeModule afin qu'il puisse accéder à PipeModule sans avoir à réimporter SharedModule, ce qui créerait un problème de dépendance circulaire, parmi d'autres problèmes.

Une autre note de bas de page à la réponse "module croisée" ci-dessus: lorsque j'ai créé le PipeModule, j'ai supprimé la méthode statique forRoot et importé le PipeModule sans celui-ci dans mon module partagé. Ma compréhension de base est que forRoot est utile pour des scénarios tels que les singletons, qui ne s'appliquent pas nécessairement aux filtres.

12
sarora

Pour Ionic, vous pouvez faire face à de multiples problèmes, comme l'a mentionné @Karl. La solution qui fonctionne parfaitement pour les pages chargées paresseux ioniques est la suivante:

  1. Créez le répertoire pipes avec les fichiers suivants: pipes.ts et pipes.module.ts

// pipes.ts content (il peut y avoir plusieurs pipes à l'intérieur, n'oubliez pas de 

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

// pipes.module.ts content

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. Inclure PipesModule dans la section des importations app.module et @NgModule

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

  2. Incluez PipesModule dans chacun de vos fichiers .module.ts où vous souhaitez utiliser des canaux personnalisés. N'oubliez pas de l'ajouter à la section imports . // Exemple. fichier: pages/my-custom-page/my-custom-page.module.ts

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

  3. C'est tout. Vous pouvez maintenant utiliser votre canal personnalisé dans votre modèle. Ex.

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

8
Timothy

Suggérant une réponse alternative ici:

Faire un module séparé pour le tuyau n'est pas obligatoire , mais c'est certainement une alternative. Vérifiez la note de bas de page des documents officiels: https://angular.io/guide/pipes#custom-pipes

Vous utilisez votre tuyau personnalisé de la même manière que vous utilisez les tuyaux intégrés.
Vous devez inclure votre canal dans le tableau de déclarations de AppModule. Si vous choisissez d'injecter votre canal dans une classe, vous devez le fournir dans le tableau de fournisseurs de votre NgModule.

Tout ce que vous avez à faire est d’ajouter votre pipe au tableau declarations et aux fournisseurs tableau dans le module où vous voulez utiliser le tuyau.

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

Remarque: Seulement si vous n'utilisez pas de modules angulaires

Pour une raison quelconque, ce n’est pas dans la documentation mais j’ai dû importer le canal personnalisé dans le composant

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

@Component({
    ...
    pipes:      [UsersPipe]
})
0
Sumama Waheed
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.
0
Chowdeswara Rao