我的 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');
}
}
下面是一个堆栈闪电战,显示了更新的示例。