128

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

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

用法:

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

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

错误:

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

角度版本:

"@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"
4

10 回答 10

171

确保您没有面临“跨模块”问题

如果使用管道的组件不属于已“全局”声明管道组件的模块,则找不到管道并且您会收到此错误消息。

在我的例子中,我已经在一个单独的模块中声明了管道,并将这个管道模块导入到任何其他具有使用管道的组件的模块中。

我已经声明您使用管​​道的组件是

管道模块

 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)

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

  @NgModule({
     imports: [
    ...
    , PipeModule.forRoot()
    ....
  ],
于 2016-11-23T17:12:39.243 回答
69

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

declarations: [ UsersPipe ],
providers: [UsersPipe]
于 2017-01-30T22:59:19.720 回答
22

对于 Ionic,您可能会面临@Karl 提到的多个问题。完美适用于离子延迟加载页面的解决方案是:

  1. 使用以下文件创建管道目录:管道.ts管道.module.ts

// pipe.ts 内容(里面可以有多个管道,记住要

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

// 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. 将 PipesModule 包含到 app.module 和 @NgModule 导入部分

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

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

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

  3. 而已。现在您可以在模板中使用自定义管道。前任。

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

于 2018-04-25T10:51:52.513 回答
13

我发现上面的“跨模块”答案对我的情况非常有帮助,但我想对此进行扩展,因为还有另一个问题需要考虑。如果你有一个子模块,它在我的测试中也看不到父模块中的管道。出于这个原因,您可能需要将管道放入自己的单独模块中。

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

  1. 从(父)SharedModule 中取出管道并放入 PipeModule
  2. 在 SharedModule 中,导入 PipeModule 并导出(对于依赖于 SharedModule的应用程序的其他部分自动获得对 PipeModule 的访问权限)
  3. 对于 Sub-SharedModule,导入 PipeModule,这样它就可以访问 PipeModule,而无需重新导入 SharedModule,否则会产生循环依赖问题等问题。

上述“跨模块”答案的另一个脚注:当我创建 PipeModule 时,我删除了 forRoot 静态方法并在我的共享模块中没有导入 PipeModule。我的基本理解是 forRoot 对于像单例这样的场景很有用,它不一定适用于过滤器。

于 2017-01-06T16:40:47.050 回答
4

在这里提出一个替代答案:

不需要为 Pipe 制作单独的模块,但绝对是一种替代方法。查看官方文档脚注:https ://angular.io/guide/pipes#custom-pipes

您使用自定义管道的方式与使用内置管道的方式相同。
您必须将管道包含在 AppModule 的声明数组中。如果你选择将你的管道注入到一个类中,你必须在你的 NgModule 的 providers 数组中提供它。

您所要做的就是将您的管道添加到声明数组中,并将提供程序数组添加到module您要使用管道的位置。

declarations: [
...
CustomPipe,
...
],
providers: [
...
CustomPipe,
...
]
于 2019-05-20T16:11:12.967 回答
1

自定义管道: 创建自定义管道时,必须在正在使用的模块和组件中注册。

export class SummaryPipe implements PipeTransform{
//Implementing transform

  transform(value: string, limit?: number): any { 
    if (!value) {
        return null;
    }
    else {
        let actualLimit=limit>0?limit:50
       return value.substr(0,actualLimit)+'...'
    } 
  }
}

添加管道装饰器

 @Pipe({
        name:'summary'
    })

并参考

import { SummaryPipe } from '../summary.pipe';` //**In Component and Module**
<div>
    **{{text | summary}}**  //Name should same as it is mentioned in the decorator.
</div>

//summary 是管道装饰器中声明的名称

于 2020-12-23T15:05:51.997 回答
0

如果您在运行测试时看到此错误,请确保您已导入管道所属的模块,例如:

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [CustomPipeModule],
            declarations: [...],
            providers: [...],
            ...
        }).compileComponents();
    }));
于 2020-10-14T12:17:26.850 回答
0

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

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

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

@Component({
    ...
    pipes:      [UsersPipe]
})
于 2016-08-17T23:11:02.823 回答
-1

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

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

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

    export class SharedPipeModule { }   

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

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

现在可以通过在嵌套模块中导入相同的内容来使用它

于 2018-01-16T14:41:57.397 回答
-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.
于 2019-03-29T06:26:11.087 回答