我设置了一个指令,该指令根据您作为参数传递的管道(@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;
}
}
预先感谢您的答复。
答案 0 :(得分:2)
与注射一样,您首先必须提供要使用的东西。
在相应的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)
答案 1 :(得分:1)
在角度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(...);