Angular - 如何将管道注入指令

问题描述 投票:0回答:2

我已经设置了一个指令,它根据你作为参数传递的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;
    }
}

在此先感谢您的回复。

angular
2个回答
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
投票

在角度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(...);
© www.soinside.com 2019 - 2024. All rights reserved.