如何在 Angular 8 中动态注入或加载管道?



我的 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 中实现这一目标?

在你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');    
}  
}

下面是一个堆栈闪电战,显示了更新的示例。

最新更新