如何全局声明管道以在不同模块中使用?


76

我有一个自定义管道,名为 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
当我导入Module1和时Module2,出现错误消息说应该在更高级别的模块中声明它。

所以我在里面声明了管道 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”

Answers:


155

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

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

有角度的文档的“基础知识”部分很好地介绍了共享模块。

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

  • 声明新的NgModule ApplicationPipesModule

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

  • 将管道工作所需的任何模块添加到 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 {}
    

4
不是你的错,但对我没用。我仍然收到模板解析错误。我已经调试了一个小时,比设置自定义管道所需的时间多了55分钟。一个非常令人沮丧的经历。
Edoardoo

2
我做过同样的事情,但收到错误消息:“找不到application-pipes.module.ts模块”
Maneesh Rao

相同的概念可用于重用指令/组件/服务(除了服务,我们需要其他配置)。很好的解释
Gangadhar JANNU

完美的作品!不要忘记将NgModule导入添加到共享模块中。import { NgModule } from '../../../../node_modules/@angular/core';
Eddy Howard

1
我需要将共享模块添加到应用程序模块导入和页面级模块导入中。我不知道为什么 我讨厌我不得不四处寻找,直到我偶然发现了这个解决方案。
山姆·巴纳姆

15

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

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

将共享模块导入到所需位置并使用它。

基本上是在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 ]
        };
      }
    }
    
  • my-module1.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 {}
    

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


5

您应该制作一个模块,即SharedModule在此处声明管道。那么你应该在出口管SharedModule和导入您SharedModule在这两个Module1Module2。Angular的文档中有一篇很棒的文章:https ://angular.io/docs/ts/latest/guide/ngmodule.html#!#shared- module


@Sajeetharan app.module导入 Module1Module2,因此在这些模块中导入管道。如果您导入SharedModuleModule1则管道将导入SharedModule并导出至Module1
Ledzz

管道具有服务依赖性,您将如何处理?
Wildhammer

@Wildhammer认为服务必须与管道在同一模块中
Ledzz

然后,每个导入将具有该服务的多个实例。那通常是不好的。
Wildhammer

3

考虑您具有以下结构:

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

 -SharedModule.ts  

在DateComponentModule中使用DatesPipeModule时。

  1. 在DatesPipeModule中声明和导出DatePipe

  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不会在管道之前加载,因此会引发错误。谢谢。我在非共享模块中声明了仅此模块的管道
juanbits '20

1

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.