Angular pipe - 获取当前元素引用

Angular pipe - get current element reference

我想访问正在使用管道的当前元素。在 Angular 中可以吗?

管道使用如下,例如<input type="text" value="'my-translation-key' | translate" />

这里是实际管道的例子

@Pipe({
  name: 'translate',
  pure: false
})
export class TranslatePipe implements PipeTransform {
  transform(key: string, params?: ITranslationSelector): string {
      // 1. Get the value by key
      // 2. Return the value

      // What I want as well:
      // this.el.nativeElement.dataset.translationKey = key;
      // Where el is current element where pipe is used
  }
}

基于您的可行性的两种可能的解决方案:

  1. 创建模板引用变量并将其作为参数发送到您的自定义管道。

自定义管道所在的位置

export class CustomPipe implements PipeTransform {
    transform(key: string, params: any): string {
        //Here param is your input element
        return 'your_value';
    }

但是在这种方法中,您在自定义管道中获取输入元素作为 HTML 元素,这可能无法满足您的要求。

  1. 在您的组件中获取输入元素作为 ViewChild,然后将其传递给自定义管道

    @ViewChild('inputRef') inputElementRef:ElementRef;

在此自定义管道中将是:

export class CustomPipe implements PipeTransform {
        transform(key: string, params: any): string {
            //Here param is your input element
            return 'your_value';
        }

通过这种方式,您可以轻松工作,但如果您在单个模板中只有一个或两个元素,这种方法会更好,因为获取多个 View Child 将不是一个干净的代码,尽管它可以正常工作。

您也可以使用模板引用变量。 模板:

<input #inputEl type="text" value="'my-translation-key' | translate: inputEl" />

Pipe ts文件部分:

export class TranslatePipe implements PipeTransform {
    transform(key: string, element?: any): string {
        // Element was marked by #inputEl template variable.
        element.dataset.translationKey = key;
    }
}

我想分享一些尝试,这些尝试并没有让我找到理想的解决方案,但也许可以引导其他人让它发挥作用。还有一个没有提到的想法。


挂接到模板管道

另一种方法是挂接到 angular 的模板创建管道。

想法: 获取 AST 并检查管道 class 并注入元素的引用并将其作为参数放入(就像之前从其他人那里提到的那样).

例如像这些人那样做的:https://github.com/typebytes/ngx-template-streams


尝试次数:

对于 pure: true,每个组件只创建一个实例管道 class。

对于 pure: false,组件中每次使用管道都会创建一个实例管道 class HTML。

您可以在管道的构造函数中注入 elementRef: ElementRef,但您只会获得对使用管道的组件的引用(在这两种情况下)。

我想也许它可以通过将另一个指令注入管道以某种方式工作,该指令引用了 HTMLElement。

示例:

<my-component>
    <div>{{'foo' | mypipe}}</div>
    <div>{{'foo' | mypipe}}</div>
    <input type="text" [value]="'bar' | mypipe">
    <input type="text" [value]="'bar' | mypipe">
</my-component>

我试图创建一个指令来为通常的 HTML 元素获取参考,如下所示:

@Directive({
    selector: 'input,div,span'
})
export class ElementRefDirective {
    constructor(public readonly elementRef: ElementRef) {}
}

但我无法将其注入 MyPipe class,反之亦然(将 MyPipe 注入指令)。