【问题标题】:How to declare a pipe globally to use in different modules?如何全局声明管道以在不同模块中使用?
【发布时间】:2017-07-23 10:02:30
【问题描述】:

我有一个名为 CurrConvertPipe 的自定义管道

import {Pipe, PipeTransform} from '@angular/core';
import {LocalStorageService} from './local-storage';
@Pipe({name: 'currConvert', pure: false})
export class CurrConvertPipe implements PipeTransform {
  constructor(private currencyStorage: LocalStorageService) {}

  transform(value: number): number {
     let inputRate = this.currencyStorage.getCurrencyRate('EUR');
    let outputputRate = this.currencyStorage.getCurrencyRate(localStorage.getItem('currency'));
    return value / inputRate * outputputRate;
  }
}

我需要在两个不同的模块中使用它,Module1Module2
当我导入Module1Module2 时,我收到一个错误,提示它应该在更高级别的模块中声明。

所以我在 app.module.ts

中声明了管道
import './rxjs-extensions';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CurrConvertPipe } from './services/currency/currency-pipe';
@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        AppRoutingModule,
        Module1,         
        Module2

    ],

    declarations: [
        AppComponent,
        CurrConvertPipe
    ],
    providers: [

    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

但是当我在Module1中使用它时,它会抛出一个错误

找不到管道“currConvert”

【问题讨论】:

    标签: angular typescript pipe angular-module


    【解决方案1】:

    在 Angular 中,共享通用指令、组件、管道等的一种好方法是使用所谓的共享模块

    这些模块声明和导出公共部分,以使它们可用于您的任何其他模块。

    角度文档的fundamentals section 是一本关于共享模块的非常好的读物。

    让我们以您的currConvert 管道为例。

    • 声明一个名为ApplicationPipesModule的新NgModule

    • 将管道添加到NgModule-decorator 元数据的declarationsexports 数组中

    • 将管道运行所需的任何模块添加到 imports数组

      // application-pipes.module.ts
      // other imports
      import { CurrConvertPipe } from './{your-path}';
      
      @NgModule({
        imports: [
          // dep modules
        ],
        declarations: [ 
          CurrConvertPipe
        ],
        exports: [
          CurrConvertPipe
        ]
      })
      export class ApplicationPipesModule {}
      
    • 将创建的ApplicationPipesModule 模块导入到将要使用管道的模块中,方法是将其添加到imports 数组中

      // my-module1.module.ts
      // other imports
      import { ApplicationPipesModule } from './{your-path}';   
      
      @NgModule({
       imports: [
         // other dep modules
         ApplicationPipesModule
       ],
       declarations: [],
       exports: []
      })
      export class MyModule1 {}
      

    【讨论】:

    • 不是你的错,但对我没有用。我仍然收到模板解析错误。我已经调试了一个小时,这比设置自定义管道所需的时间多 55 分钟。一次非常令人沮丧的经历。
    • 我做了同样的事情,但我收到错误:“application-pipes.module.ts module not found”
    • 同样的概念可以用于重用指令/组件/服务(除了服务我们需要额外的配置)。很好的解释
    • 完美运行!不要忘记将 NgModule 导入添加到共享模块中。 import { NgModule } from '../../../../node_modules/@angular/core';
    • 我需要将我的共享模块添加到应用程序模块导入和我的页面级模块导入中。我不知道为什么。我讨厌在偶然发现这个解决方案之前我不得不四处乱窜。
    【解决方案2】:

    您可以使用共享模块来共享您的服务、指令、管道、组件

    您必须创建一个模块并导入管道、指令、服务或组件,并为服务设置声明、导出和提供者。

    将共享模块导入到您想要的任何地方并使用它。

    基本上管道和指令在 NgModules 元数据中声明和导出。 对于服务定义 forRoot,它返回提供者以访问其他模块。

    • shareModule.ts

      
      import { NgModule, ModuleWithProviders } from '@angular/core';
      import { appDirective } from './{your-path}';
      import { appPipe } from './{your-path}';
      import { appService } from './{your-path}';
      
      @NgModule({
        declarations: [
          appPipe,
          appDirective
        ],
        exports: [
          appPipe,
          appDirective
        ]
      })
      export class SharingModule {
        static forRoot(): ModuleWithProviders {
          return {
            ngModule: SharingModule,
            providers: [ appService ]
          };
        }
      }
      
    • 我的模块1.module.ts

      
      import { BrowserModule } from '@angular/platform-browser';
      import { NgModule } from '@angular/core';
      
      import { myComponent } from './{your-path}';
      
      import { SharingModule } from './{your-path}';
      
      @NgModule({
        declarations: [
          myComponent
        ],
        imports: [
          BrowserModule,
          SharingModule.forRoot()  
        ],
      })
      export class AppModule {}
      

    同样,您也可以在其他模块中执行此操作。

    【讨论】:

      【解决方案3】:

      您应该创建一个模块,即SharedModule 并在那里声明您的管道。然后你应该在SharedModule 中导出管道并在Module1Module2 中导入你的SharedModule。 Angular 的文档中有一篇很棒的文章:https://angular.io/docs/ts/latest/guide/ngmodule.html#!#shared-module

      【讨论】:

      • @Sajeetharan app.module imports Module1Module2,因此在这些模块中导入管道。如果您在Module1 中导入SharedModule,则管道会在SharedModule 中导入并导出到Module1
      • 管道有服务依赖,你会怎么处理?
      • @Wildhammer 认为服务必须与管道位于同一模块中
      • 那么每次导入都会有该服务的多个实例。这通常是不行的。
      【解决方案4】:

      假设你有这样的结构:

      app 
       -shared
         -components
           -DateComponentModule.ts
         -pipes
           -DatesPipe
           -DatesPipeModule.ts
      
       -SharedModule.ts  
      

      当您在 DateComponentModule 中使用 DatesPipeModule 时。

      1. 在 DatesPipeModule 中声明和导出 DatesPipe

      2. 现在将 DatesPipeModule 直接导入 DateComponentModule。

      DatesPipeModule.ts

      import { DatesPipe} from './{your-path}';
      
      @NgModule({
        imports: [],
        declarations: [ 
          DatesPipe
        ],
        exports: [
          DatesPipe
        ]
      })
      export class DatesPipeModule{}
      
      

      DateComponentModule.ts

      import { DatesPipeModule} from './{your-path}';
      
      @NgModule({
        imports: [DatesPipeModule],
        declarations: [],
        exports: []
      })
      export class DatesPipeModule{}
      

      你也可以从SharedModule导出,在DatesComponentModule.ts导入,但是SharedModule不会在管道之前加载,所以会报错。

      【讨论】:

      • 哦,我看到了您所说的问题:但是 SharedModule 不会在管道之前加载,因此会引发错误。谢谢。我在非共享模块中声明了仅用于该模块的管道
      【解决方案5】:

      如果您使用 CLI 为共享模块生成管道,则需要手动将管道添加到“导出”列表中。我的管道在浏览器中出错,直到我将管道作为导出添加到我导入/声明的共享模块中。

      【讨论】:

        猜你喜欢
        • 2019-01-04
        • 1970-01-01
        • 1970-01-01
        • 2016-05-19
        • 1970-01-01
        • 2018-01-26
        • 2017-05-21
        • 2017-02-08
        • 1970-01-01
        相关资源
        最近更新 更多