关于angular:找不到管道”angular2自定义管道

The pipe ' ' could not be found angular2 custom pipe

我似乎无法解决此错误。 我有一个搜索栏和一个ngFor。 我试图使用这样的自定义管道过滤数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
  }
}

用法:

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


...

错误:

1
2
3
4
5
zone.js:478 Unhandled Promise rejection: Template parse errors:
The pipe 'usersPipe' could not be found ("

    <div  
    [ERROR ->]*ngFor="let user of (user | usersPipe:searchTerm)">

角版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"@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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 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: [],
      };
   }
 }

在其他模块(例如app.module)中的用法

1
2
3
4
5
6
7
8
9
10
  // Import APPLICATION MODULES
  ...
  import { PipeModule }    from './tools/PipeModule';

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


您需要在模块声明中包含管道:

1
2
declarations: [ UsersPipe ],
providers: [UsersPipe]


对于Ionic,@ Karl提到您可能会遇到多个问题。对于离子型惰性加载页面而言,完美解决方案是:

  • 使用以下文件创建管道目录:pipes.ts和pipes.module.ts
  • // pipe.ts内容(其中可以有多个管道,请记住

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import { NgModule } from"@angular/core";
    import { IonicModule } from"ionic-angular";
    import { toArrayPipe } from"./pipes";

    @NgModule({
      declarations: [toArrayPipe],
      imports: [IonicModule],
      exports: [toArrayPipe]
    })
    export class PipesModule {}
  • 将PipesModule包含到app.module和@NgModule导入部分中

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

  • 在您要使用自定义管道的每个.module.ts中包括PipesModule。不要忘记将其添加到导入部分。
    //示例。文件:pages / my-custom-page / my-custom-page.module.ts

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

  • 而已。现在,您可以在模板中使用自定义管道。例如

  • {{ prop.key }}


    我发现上面的"跨模块"答案对我的情况非常有帮助,但由于需要考虑的其他问题,我想对此进行扩展。如果您有子模块,那么在我的测试中它也看不到父模块中的管道。因此,您可能需要将管道放入自己的单独模块中。

    这是我为解决子模块中不可见的管道而采取的步骤的摘要:

  • 从(父)SharedModule中取出管道,然后放入PipeModule中
  • 在SharedModule中,导入PipeModule并导出(对于依赖于SharedModule的应用程序的其他部分,以自动获得对PipeModule的访问权限)
  • 对于Sub-SharedModule,请导入PipeModule,以便它可以访问PipeModule,而无需重新导入SharedModule,这将导致循环依赖问题以及其他问题。
  • 上述"跨模块"答案的另一个脚注:创建PipeModule时,我删除了forRoot静态方法,并在共享模块中导入了不带静态方法的PipeModule。我的基本理解是forRoot对于单例之类的场景很有用,这些场景不一定适用于过滤器。


    在这里建议一个替代答案:

    不需要为管道创建单独的模块,但绝对是一种选择。检查官方文档脚注:https://angular.io/guide/pipes#custom-pipes

    You use your custom pipe the same way you use built-in pipes.
    You must include your pipe in the declarations array of the AppModule .
    If you choose to inject your pipe into a class, you must provide it in the providers array of your NgModule.

    您所要做的就是将管道添加到声明数组,并在要使用管道的module中添加providers数组。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    declarations: [
    ...
    CustomPipe,
    ...
    ],
    providers: [
    ...
    CustomPipe,
    ...
    ]


    注意:仅当您不使用角度模块时

    由于某种原因,这不在文档中,但我必须在组件中导入自定义管道

    1
    2
    3
    4
    5
    6
    import {UsersPipe} from './users-filter.pipe'

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


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    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.

    我在存在管道的同一目录中为管道创建了一个模块

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import { NgModule } from '@angular/core';
    ///import pipe...
    import { Base64ToImage, TruncateString} from './'  

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

        export class SharedPipeModule { }

    现在,将该模块导入app.module中:

    1
    2
    3
    4
    5
    6
    7
    import {SharedPipeModule} from './pipe/shared.pipe.module'
     @NgModule({
         imports: [
        ...
        , PipeModule.forRoot()
        ....
      ],

    现在,可以通过将其导入嵌套模块中来使用它