Как объявить трубу глобально для использования в разных модулях?

У меня есть пользовательский канал с именем 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;
  }
}

Мне нужно использовать это в двух разных модулях, Module1 и Module2.
Когда я импортирую в 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' не найден

Ответы

Ответ 1

В Angular хорошей техникой для совместного использования общих директив, компонентов, каналов и т.д. Является использование так называемого общего модуля.

Эти модули объявляют и экспортируют общие части, чтобы их можно было использовать для любых других ваших модулей.

Раздел " Основы" угловой документации - очень хорошее прочтение об общих модулях.

Давайте возьмем в качестве примера ваш currConvert pipe.

  • Объявите новый NgModule под названием ApplicationPipesModule

  • Добавьте канал в declarations и exports массивы метаданных NgModule -decorator.

  • Добавьте любые модули, которые могут потребоваться для вашей трубы, чтобы работать на 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 {}
    

Ответ 2

Вы должны сделать модуль, т.е. SharedModule, и объявить там свой канал. Затем вы должны экспортировать трубку в SharedModule и импортировать SharedModule как в Module1, так и в Module2. Там есть замечательная статья в Angular docs: https://angular.io/docs/ts/latest/guide/ngmodule.html#!#shared-module

Ответ 3

вы можете использовать модули общего доступа для обмена вашими услугами, директивами, трубами, компонентами

Вы должны создать модуль и импортировать каналы, директивы, сервисы или компоненты и установить декларацию, экспорт и поставщиков для сервисов.

импортируйте модуль обмена в то место, где вы хотите, и используйте его.

в основном каналы и директивы, объявленные и экспортированные в метаданные 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 ]
        };
      }
    }
    
  • мой-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 {}
    

Как мудрый вы можете сделать и в других модулях.

Ответ 4

Если вы генерируете канал, используя CLI для общего модуля, вам нужно будет добавить канал в список "экспорт" вручную. Ошибка моего канала передавалась в браузере до тех пор, пока я не добавил канал в качестве экспорта в общий модуль, в который я импортировал/объявил его.