Wie deklariere ich eine Pipe global für die Verwendung in verschiedenen Modulen?


74

Ich habe eine benutzerdefinierte Pipe namens 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;
  }
}

Ich muss dies in zwei verschiedenen Modulen verwenden, Module1und Module2.
Beim Importieren in Module1und Module2wird die Fehlermeldung angezeigt, dass es in einem übergeordneten Modul deklariert werden soll.

Also erkläre ich das Rohr im 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 { }

Aber wenn ich es benutze Module1, wird ein Fehler ausgegeben

Die Pipe 'currConvert' wurde nicht gefunden

Antworten:


152

In Angular besteht eine gute Technik zum Teilen gemeinsamer Anweisungen, Komponenten, Pipes usw. darin, ein sogenanntes gemeinsames Modul zu verwenden .

Diese Module deklarieren und exportieren gemeinsame Teile, damit sie für alle anderen Module verwendet werden können.

Der Abschnitt mit den Grundlagen der eckigen Dokumentation enthält eine sehr gute Lektüre über gemeinsam genutzte Module.

Nehmen wir als Beispiel Ihre currConvertPfeife.

  • Deklarieren Sie das neue NgModule mit dem Namen ApplicationPipesModule

  • Fügen Sie die Pipe zu den declarationsund exportsArrays der NgModule-decorator-Metadaten hinzu

  • Fügen Sie dem importsArray alle Module hinzu, die möglicherweise erforderlich sind, damit Ihre Pipe funktioniert

    // application-pipes.module.ts
    // other imports
    import { CurrConvertPipe } from './{your-path}';
    
    @NgModule({
      imports: [
        // dep modules
      ],
      declarations: [ 
        CurrConvertPipe
      ],
      exports: [
        CurrConvertPipe
      ]
    })
    export class ApplicationPipesModule {}
    
  • Importieren Sie das erstellte ApplicationPipesModuleModul in die Module, in denen Ihre Pipe verwendet werden soll, indem Sie es dem importsArray hinzufügen

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

4
Nicht dass es deine Schuld wäre, aber es hat bei mir nicht funktioniert. Ich erhalte immer noch die Fehler beim Analysieren der Vorlage. Ich habe dieses Ding eine Stunde lang debuggt, das sind 55 Minuten mehr als nötig, um eine benutzerdefinierte Pipe einzurichten. Eine sehr frustrierende Erfahrung.
Edoardoo

2
Ich habe das gleiche getan, aber ich erhalte die Fehlermeldung: "application-pipes.module.ts Modul nicht gefunden"
Maneesh Rao

Das gleiche Konzept kann für die Wiederverwendung von Anweisungen / Komponenten / Diensten verwendet werden (außer für Dienste benötigen wir zusätzliche Konfiguration). Schöne Erklärung
Gangadhar JANNU

Funktioniert perfekt! Vergessen Sie nicht, den NgModule-Import zum freigegebenen Modul hinzuzufügen. import { NgModule } from '../../../../node_modules/@angular/core';
Eddy Howard

1
Ich musste mein freigegebenes Modul sowohl zu den App-Modul-Importen als auch zu den Modul-Importen auf Seitenebene hinzufügen. Ich weiß nicht warum. Ich hasse es, dass ich herumwirbeln musste, bis ich über diese Lösung stolperte.
Sam Barnum

14

Sie können Freigabemodule verwenden, um Ihren Dienst, Ihre Direktive, Ihre Pipes und Ihre Komponenten freizugeben

Sie müssen ein Modul erstellen und die Pipes, Direktiven, Dienste oder Komponenten importieren und die Deklaration, den Export und die Anbieter für die Dienste festlegen.

Importieren Sie das Freigabemodul an einen beliebigen Ort und verwenden Sie es.

Grundsätzlich werden Pipes und Direktiven in NgModules-Metadaten deklariert und exportiert. Für Dienste definieren Sie forRoot, das die Anbieter zurückgibt, um auf andere Module zuzugreifen.

  • 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 {}
    

Wie weise können Sie auch in anderen Modulen tun.


5

Sie sollten ein Modul erstellen, dh SharedModuleIhre Pipe dort deklarieren. Dann sollten Sie Pipe-In exportieren SharedModuleund Ihre SharedModulein beiden Module1und importieren Module2. Es gibt einen großartigen Artikel in Angulars Dokumenten: https://angular.io/docs/ts/latest/guide/ngmodule.html#!#shared-module


@Sajeetharan app.module importiert Module1 und Module2, daher wird Pipe in diesen Modulen nicht importiert. Wenn Sie importieren SharedModulein Module1dann Rohr wird in importiert SharedModuleund exportiert inModule1
Ledzz

Die Pipe ist dienstabhängig. Wie würden Sie damit umgehen?
Wildhammer

@ Wildhammer denken, dass Service im gleichen Modul mit Pipe kommen muss
Ledzz

Dann hätten Sie mehrere Instanzen dieses Dienstes pro Import. Das ist normalerweise nicht in Ordnung.
Wildhammer

1

Wenn Sie eine Pipe mithilfe der CLI für ein freigegebenes Modul generieren, müssen Sie die Pipe manuell zur Liste "Exporte" hinzufügen. Mein Pipe-Fehler wurde im Browser angezeigt, bis ich die Pipe als Export in mein freigegebenes Modul hinzufügte, in das ich sie importiert / deklariert habe.


0

Angenommen, Sie haben diese Struktur:

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

 -SharedModule.ts  

Wenn Sie DatesPipeModule in DateComponentModule verwenden.

  1. Deklarieren und exportieren Sie DatesPipe in DatesPipeModule

  2. Importieren Sie jetzt DatesPipeModule direkt in 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{}

Sie können es auch exportieren SharedModuleund importieren, es DatesComponentModule.tswird jedoch SharedModulenicht vor Pipes geladen, sodass ein Fehler ausgegeben wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.