我已经设置了一个指令,它根据你作为参数传递的de pipe(@Input)为输入值赋予格式。我用它作为反应形式。
为此,我需要导入所有需要的管道(现在一个),并提供一个开关以使用正确的管道。
我的问题是:有没有办法从注入器获取任何管道只知道它的令牌,如const pipe = injector.get(‘currency’)
;
这是我的指令代码:
import { Input, Renderer2, ElementRef, forwardRef, Directive, HostListener } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { CurrencyPipe } from '@angular/common';
@Directive({
selector: '[formatInput]',
providers: [
{ provide: NG_VALUE_ACCESSOR, multi: true, useExisting: forwardRef(() => FormatInputDirective) },
],
})
export class FormatInputDirective implements ControlValueAccessor {
private changeCallback: Function;
private touchedCallback: Function;
@Input() pipe: any; // { token: string, args: any[] }
@HostListener('input', ['$event.target.value'])
onChange(value) {
this.changeCallback(value);
}
@HostListener('blur', ['$event.target'])
onBlur(target) {
this.touchedCallback();
}
constructor(private renderer: Renderer2, private currency: CurrencyPipe, private elRef: ElementRef ) {
this.changeCallback = (_: any) => {};
this.touchedCallback = () => {};
}
writeValue(value: any): void {
this.renderer.setProperty(this.elRef.nativeElement, 'value', this.setPipedValue(value));
}
setPipedValue(value: any): any {
if (!this.pipe || !value) {
return value;
} else {
let pipe;
switch (this.pipe.token) {
case 'currency':
pipe = this.currency;
break;
}
return pipe.transform(value, ...this.pipe.args);
}
}
registerOnChange(fn) {
this.changeCallback = fn;
}
registerOnTouched(fn: any): void {
this.touchedCallback = fn;
}
}
在此先感谢您的回复。
像往常一样注射,你首先必须提供你想要使用的东西。在相应的NgModule
中,将CurrencyPipe
(以及之后要注入的所有其他内容)添加到providers
数组中。
providers: [CurrencyPipe],
现在注入Injector
,将其添加到指令的构造函数中。
constructor (private injector: Injector)
使用它来使用get
方法和令牌作为参数来获取所需的管道实例。在这种情况下,令牌是类本身。
const pipe = injector.get(CurrencyPipe)
现在你有一个管道实例。您可以使用其transform
方法执行转换。
this.value = pipe.transform(123456789)
你可以see this in action on StackBlitz
请注意,Angular没有使用字符串的依赖注入概念。您可以使用令牌代替,但这并不会为您提供与管道中的类已有的相比更多的功能。
如果要将管道指定为字符串,则必须自己定义映射。
const MAP = { 'currency': CurrencyPipe, 'decimal': DecimalPipe }
现在使用此映射生成正确管道的实例。
const pipeName = 'currency'
const pipeClass = MAP[pipeName]
const pipe = injector.get(pipeClass)
const value = pipe.transform(input)
在角度6过滤方法中也直接从@angular/common
包中输出,例如:
import { formatCurrency } from '@angular/common';
https://angular.io/api/common/formatCurrency
或者您可以自己实例化管道,而不使用DI,因为它是简单的帮助程序类,没有任何依赖关系:
import { CurrencyPipe } from '@angular/common';
const pipe = new CurrencyPipe('en-US');
pipe.transform(...);