Je veux accéder à l'élément actuel dans lequel le tuyau est utilisé. Est-ce possible dans Angular?

Le tuyau est utilisé comme suit, par ex. <input type="text" value="'my-translation-key' | translate" />

Voici un exemple du tuyau réel

@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
  }
}
4
Stan 28 nov. 2017 à 21:40

3 réponses

Meilleure réponse

Deux solutions possibles en fonction de votre faisabilité:

  1. Créez une variable de référence de modèle et envoyez-la en tant que paramètre à votre Pipe personnalisée.

Où se trouve le tuyau personnalisé

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

Mais dans cette approche, vous obtenez un élément d'entrée dans un tube personnalisé en tant qu'élément HTML qui peut ne pas répondre à vos besoins.

  1. Récupérez l'élément d'entrée en tant que ViewChild dans votre composant, puis transmettez-le au tuyau personnalisé

    @ViewChild ('inputRef') inputElementRef: ElementRef;

Dans ce tuyau personnalisé sera:

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

Grâce à cela, vous pouvez travailler facilement, mais cette approche est meilleure si vous n'avez qu'un ou deux éléments dans un seul modèle, car la récupération de plusieurs View Child ne sera pas un code propre, même si cela fonctionnera correctement.

2
Ankit Kapoor 28 nov. 2017 à 19:13

Je voudrais partager quelques tentatives qui ne m'ont pas conduit à la solution souhaitée, mais qui pourraient peut-être amener quelqu'un d'autre à la faire fonctionner. Aussi une autre idée qui n'a pas encore été mentionnée.


Accrochez-vous au pipeline de création de modèles

Une autre façon pourrait être de s'accrocher au modèle créant un pipeline angulaire.

Idée: Obtenez l'AST et vérifiez la classe de tuyau, injectez la référence de l'élément et placez-la en tant que paramètre (comme mentionné précédemment par d'autres).

Par exemple, comme ces gars-là l'ont fait: https://github.com/typebytes/ngx-template- flux


Tentatives:

Avec pure: true, il n'y a qu'une seule classe de canal d'instance créée par composant.

Avec pure: false, une classe de canal d'instance est créée pour chaque utilisation du canal dans le HTML de vos composants.

Vous pouvez injecter elementRef: ElementRef dans le constructeur du tube, mais vous n'obtiendrez que la référence au composant dans lequel le tube est utilisé (dans les deux cas).

J'ai pensé que cela pourrait peut-être fonctionner d'une manière ou d'une autre avec une autre directive injectée dans le tuyau qui fait référence au HTMLElement.

Exemple:

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

J'ai essayé de créer une directive pour obtenir une référence pour les HTMLElements habituels qui ressemblaient à ceci:

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

Mais je n'ai pas pu l'injecter dans la classe MyPipe, ni l'inverse (obtenir le MyPipe injecté dans la directive).

0
Stefan Rein 28 avril 2020 à 07:16

Vous pouvez également utiliser une variable de référence de modèle. Modèle:

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

La partie du fichier Pipe ts:

export class TranslatePipe implements PipeTransform {
    transform(key: string, element?: any): string {
        // Element was marked by #inputEl template variable.
        element.dataset.translationKey = key;
    }
}
2
Chenna 3 mars 2020 à 12:52
47538701