Как динамически ввести или загрузить трубу в Angular 8? - PullRequest
0 голосов
/ 24 сентября 2019

В моем приложении Angular 8 есть следующий пользовательский канал:

import { Pipe, PipeTransform } from '@angular/core';
import { MyService} from '../_services/my.service';

@Pipe({
    name: 'myPipe'
})
export class MyPipe implements PipeTransform {
    constructor(private myService: MyService) {}

    transform(value: string): any {
        return this.myService.loadForID(value);
    }
}

Я пытаюсь динамически преобразовать значение в коде компонента, используя только строковое имя: 'myPipe' но я все равно не могу найти, чтобы динамически внедрить / загрузить канал для строки. онлайн-сообщение, которое я нашел предлагает следующий код, но даже для этого требуется тип (MyService), а не строка

constructor(private injector:Injector) {
  injector.get(MyService);
}

есть способ добиться этого в Angular?

1 Ответ

1 голос
/ 24 сентября 2019

В вас app.module вы можете использовать строку:

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ],
  providers: [
    MyPipe,
    { provide: 'myPipe', useClass: MyPipe }
  ]
})
export class AppModule { }

Затем вы можете вставить ее в свой компонент:

import { Component, Injector } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  constructor(private injector:Injector){
    var myInterface = injector.get('myPipe');
    myInterface.transform('test');
  }  
}

Вот стек стека показывая пример

РЕДАКТИРОВАТЬ

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

Сначала создайте службу, чтобы сопоставить строку с ожидаемым токеном инъекции:

@Injectable()
export class TokenService {
  static MY_PIPE_TOKEN = new InjectionToken<MyPipe>('myPipe');

  getToken(name: string): InjectionToken<any> {
    if (name === 'myPipe') {
      return TokenService.MY_PIPE_TOKEN;
    } else {
      throw `No token with name ${name} found`;
    }
  }
}

Настройте своих провайдеров, используя токен инъекции из службы:

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ],
  providers: [
    TokenService,
    MyPipe,
    { provide: TokenService.MY_PIPE_TOKEN, useClass: MyPipe }
  ]
})
export class AppModule { }

В компоненте используйте службу, чтобы получить правильный токен:

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  constructor(private injector:Injector, private tokenService: TokenService){    
    let myInterface = injector.get(tokenService.getToken('myPipe'));
    myInterface.transform('test');    
  }  
}

Вот astackblitz , показывающий обновленный пример.

...