【问题标题】:Angular custom pipe not working 'pipe not found'角度自定义管道不起作用“找不到管道”
【发布时间】:2020-07-23 16:17:14
【问题描述】:

我正在尝试在我的 Angular 应用程序中创建一个自定义管道,但不断收到“找不到名称为“currencyFormat”的管道”错误消息。我使用 Angular CLI 创建了管道:ng g pipe /components/pipes/currency-format,代码如下所示:

import { formatNumber } from '@angular/common';

@Pipe({
  name: 'currencyFormat'
})
export class CurrencyFormatPipe implements PipeTransform {
  transform(value: any, currency: string): any {
    const currencySymbol = (currency == 'EUR' ? '€' : '$');
    let formattedValue = `${currencySymbol} ${formatNumber(value, 'be', '1.2-2')}`;
    return formattedValue;
  }

}

因为我使用 Angular CLI 创建管道,所以管道会自动添加到 app.module.ts 的声明中。我正在尝试在我的一个页面(home.page.html)中使用管道,但我仍然收到此错误。到目前为止,我已经尝试了许多不同的方法,包括将管道放在单独的模块中并尝试导入该模块,但没有任何成功。

任何想法这个问题可能是什么?

编辑:这也是我的 app.module.ts,以防它有用:

import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { ComponentsModule } from 'src/app/components/components.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ChartsModule } from 'ng2-charts';
import { environment } from "src/environments/environment";
import { AngularFireModule } from "@angular/fire";
import { AngularFirestoreModule } from "@angular/fire/firestore";
import { ServiceWorkerModule } from '@angular/service-worker';
import { CurrencyFormatPipe } from './components/pipes/currency-format.pipe';

@NgModule({
  declarations: [AppComponent, CurrencyFormatPipe],
  entryComponents: [],
  imports: [
    BrowserModule, 
    IonicModule.forRoot({ animated: true, mode: 'ios' }), 
    AppRoutingModule, 
    ComponentsModule,
    BrowserAnimationsModule,
    ChartsModule,
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFirestoreModule,
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
  ],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

【问题讨论】:

  • 您有home.module.ts 文件吗?如果这样做,您是否将您的 CurrencyFormatPipe 添加到 home.module.ts 声明数组中?
  • 嗨@DJHouse,如果我同时添加它,我会收到错误The Pipe 'CurrencyFormatPipe' is declared by more than one NgModule.
  • 啊,我知道什么会起作用。我会发布一个答案。

标签: angular


【解决方案1】:

如果你有多个模块,我相信你需要在AppModule之外的一个辅助模块中声明管道,并在其他模块(包括AppModule)中导入该模块才能使用它。

我不确定为什么AppModule 中声明的管道没有来自其他模块的全局访问权限。它在某种程度上违背了 Angular 的延迟加载机制。

试试下面的

@NgModule({
    imports: [],
    declarations: [ CurrencyPipe ],
    exports: [ CurrencyPipe ]
})
export class ComponentsModule { }
@NgModule({
    imports: [ BrowserModule, HttpModule, FormsModule, ComponentsModule ],
    declarations: [ AppComponent ],
    bootstrap: [ AppComponent ]
})
export class AppModule { }

然后,当您需要在其他模块中使用它时,您需要导入声明管道的模块(在此示例中为ComponentModule)。

【讨论】:

    【解决方案2】:

    解决此问题的最佳方法是拥有一个通用的共享模块。这是 Angular 中的常见模式。

    给定一个示例文件夹/应用程序结构:

    
    app
    ├── home
    │   ├── home.component.ts
    │   ├── home.module.ts
    │   └── ...
    ├── shared
    │   └── shared.module.ts
    ├── app.module.ts
    └── ...
    

    然后,您在 多个其他模块 需要的 shared.module 中声明和导出组件、管道、指令、模块等。

    shared.module.ts

    import { NgModule } from '@angular/core';
    
    @NgModule({
      declarations: [
        /* declare it once, here */
        CurrencyFormatPipe
      ],
      exports: [
        /* then export it */
        CurrencyFormatPipe
      ]
    })
    export class SharedModule { }
    

    您的所有其他模块只会导入您的 shared.module 并能够使用共享模块导出的任何内容。

    app.module.ts

    @NgModule({
      declarations: [AppComponent],
      entryComponents: [],
      imports: [
        BrowserModule, 
        /* import your shared module here */
        SharedModule,
    
        IonicModule.forRoot({ animated: true, mode: 'ios' }), 
        AppRoutingModule, 
        ComponentsModule,
        BrowserAnimationsModule,
        ChartsModule,
        AngularFireModule.initializeApp(environment.firebaseConfig),
        AngularFirestoreModule,
        ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
      ],
      providers: [
        StatusBar,
        SplashScreen,
        { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    

    然后你也可以将它导入到你的 home.module.ts

    @NgModule({
      declarations: [/* other imports */],
      entryComponents: [],
      imports: [
        /* import your shared module here, you will have access to the currency pipe now */
        SharedModule
      ],
    })
    export class AppModule {}
    

    希望对您有所帮助。 Here are the Angular docs 关于共享模块。

    【讨论】:

      最近更新 更多