web-dev-qa-db-fra.com

Obtenir un élément parent polymère

Donc, j'utilise Polymer depuis environ un jour maintenant et j'ai du mal à formuler cette question. Par conséquent, si mon approche est très différente, veuillez ne pas ressentir le besoin de résoudre ce problème, mais orientez-moi plutôt dans la bonne direction.

Ce que j'ai sont des éléments personnalisés au sein des éléments personnalisés et je voudrais qu'un élément enfant affecte les attributs du parent. L'approche que je suis en train de faire consiste à créer un gestionnaire de clic, en fermant l'élément parent dans un IIFE, puis en transmettant ce gestionnaire au sous-composant. Ainsi...

Polymer({
  ready: function(){
     this.superHandler = (function(p) {
        return function() {
          // "this" here will be the sub-component
          p.title = this.title;
        }
     })(this);
  }
});

Où l'élément parent l'utilise dans son modèle comme ...

<polymer-element name="parent-element">
  <template>
    <sub-element on-click={{superHandler}} />
  </template>
</polymer-element>

Ceci (dans mon vrai code, bien qu'il soit possible qu'il y ait des fautes de frappe ici) fonctionne dans tout, sauf dans IE, et je sais que IE n'est pas officiellement supporté, mais il est si proche que je ne veux pas l'abandonner. . Les choses que je veux éviter sont les références répétées aux parentNodes et shadowRoots pour aller au parent que je cherche.

Modifier

J'ai oublié de mentionner comment cela échoue dans IE et pourquoi je veux éviter l'appel de parentNode. Dans IE, lorsqu'il envoie l'événement en particulier à la ligne 9131 de polymer.js, la variable "méthode" et la référence dans obj [méthode] sont des chaînes dans IE, et aucune méthode n'est donc appliquée. Si je veux éviter le parentNode, c'est parce que l'appelant n'est pas le parent direct. Je ne veux donc pas continuer à obtenir des parentNodes tant que je n'ai pas trouvé le bon, car le code est beaucoup plus compréhensible lorsque je peux nommer la variable.

Modifier 2

Ce que je vais faire maintenant (puisqu'il fonctionne dans IE9), même si je laisse la question ouverte pour une meilleure réponse est de continuer avec le IIFE, en retournant une fonction qui prend un argument qui est l'enfant. Ensuite, l'enfant trouvera le parent d'intérêt par un querySelector. Cela signifie que l'enfant doit avoir une connaissance préalable du parent et de la méthode à suivre, ce qui n'est pas idéal, mais ... IE.

Alors le parent le configure comme ...

Polymer('parent-element', {
  ready: function(){
     this.superHandler = (function(p) {
        return function(child) {
          p.title = chile.title;
        }
     })(this);
  }
});

Et l'enfant doit l'obtenir par un sélecteur de requête, par exemple par 'élément-parent' et connaître le nom 'superHandler' (pas le nom réel)

Polymer('child-element',{
        clickHandler: function(){
            var p = document.querySelector('parent-element').superHandler;
            p(this);
        }
    });

De meilleures idées?

12
Felix

Merci pour les suggestions d'événements personnalisés. Cela m'a amené à revenir en arrière et à regarder à nouveau les éléments centraux pour trouver ceci .

Ensuite, j'ai juste besoin d'ajouter un 

<core-signals on-core-signal-my-event="{{myEventHandler}}"></core-signals>

Déclenchez un événement "core-signal" avec le nom (dans cet exemple) "my-event" et créez une méthode "myEventHandler" sur le parent, par exemple.

Polymer({
  myEventHandler: function(e,detail,sender) {...}
})
1
Felix

Vous pouvez utiliser vos propres événements pour transmettre des données entre des éléments.

Composant parent:

<polymer-element name="parent-element">
  <template>
    <!-- ... -->
    <sub-element></sub-element>
  </template>
  <script>
  Polymer({
    ready: function() {
      this.addEventListener('eventFromChild', this.myAction);
    },
    myAction: function(event) {
      console.log(event.detail);
    },
  });
  </script>

Composant enfant:

<polymer-element name="sub-element" attributes="foo bar">
  <template>
    <!-- ... -->
    <button on-click="{{passParams}}">Send</button>
  </template>
  <script>
  Polymer({
    ready: function() {
      this.foo = 'abc';
      this.bar = '123';
    },
    passParams: function() {
      this.fire('eventFromChild', { foo: this.foo, bar: this.bar });
    },
  });
</script>
16
Max Zuber

Voici un moyen simple d’avoir accès à l’élément parent en Javascript. Cela fonctionne dans un travail personnel (polymère 0.5 - comme mentionné dans les commentaires, les choses sont différentes dans 1.0). Non testé sur IE, mais il me semble une solution simple:

Polymer('sub-element', {
  ready: function(){
     this.parentNode;
  }
});
3
bdulac

En raison de la nature d'un composant, j'hésite à accéder au parentNode de cette manière. Si vous avez besoin de style, vous pouvez vous en passer en utilisant les règles :Host() css. À mon humble avis, il semble difficile de contacter l'élément parent à moins que vous n'ayez une bonne raison. Pourquoi ne pas utiliser un événement personnalisé ou un magasin intermédiaire tel que localStorage?

Consultez également "La liste de contrôle" Gold Standard "pour les composants Web" pour obtenir une aide supplémentaire sur les meilleures pratiques. 

0
Erik Isaksen