最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Polymer 1.0: How to pass an event to a child-node element without using <iron-signals>? - Stack Overf

programmeradmin4浏览0评论

This Stack Overflow answer suggests using <iron-signals> to broadcast an event down the DOM tree to a custom element.

Below, I ask a different question.

Question

How do I:

  • pass an event down to a direct child node (custom element)
  • from a parent (custom element)
  • without using <iron-signals>?

Code

This is what I have so far. But it doesn't work.

parent-element.html
<dom-module id="parenet-element">   
  <template is="dom-bind">
    <child-element></child-element>
    <paper-button on-tap="_handleTap"></paper-button>
  </template>
</dom-module>
<script>
  (function(){
    Polymer({
      is: 'parenet-element',
      _handleTap: function() {
        this.fire("my-event");
      }
    });
  })();
</script>
child-element.html
<dom-module id="child-element"> 
...
</dom-module>
<script>
  (function(){
    Polymer({
      is: 'child-element',
      listeners: {
        "my-event": "foo"
      },
      foo: function(){
        // Do stuff
      }
    });
  })();
</script>

This Stack Overflow answer suggests using <iron-signals> to broadcast an event down the DOM tree to a custom element.

Below, I ask a different question.

Question

How do I:

  • pass an event down to a direct child node (custom element)
  • from a parent (custom element)
  • without using <iron-signals>?

Code

This is what I have so far. But it doesn't work.

parent-element.html
<dom-module id="parenet-element">   
  <template is="dom-bind">
    <child-element></child-element>
    <paper-button on-tap="_handleTap"></paper-button>
  </template>
</dom-module>
<script>
  (function(){
    Polymer({
      is: 'parenet-element',
      _handleTap: function() {
        this.fire("my-event");
      }
    });
  })();
</script>
child-element.html
<dom-module id="child-element"> 
...
</dom-module>
<script>
  (function(){
    Polymer({
      is: 'child-element',
      listeners: {
        "my-event": "foo"
      },
      foo: function(){
        // Do stuff
      }
    });
  })();
</script>
Share Improve this question edited Oct 20, 2020 at 20:20 Brian Tompsett - 汤莱恩 5,88372 gold badges61 silver badges133 bronze badges asked Sep 24, 2015 at 20:40 Let Me Tink About ItLet Me Tink About It 16.1k21 gold badges108 silver badges217 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 11

You definitely can. Without iron-signals you've got three options (that I currently know of):

  1. Get the parent and have the child attach an event listener to the parent
  2. The parent can have the child fire the same event
  3. You mentioned that events only go up. You can then make the child element listen to the document firing that event (but I think this is bad)

Here's an example

<!doctype html>
<html>

<head>
  <base href="http://polygit.org/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">
</head>

<body>
  <dom-module id="parent-element">
    <template>
      <child-element></child-element>
      <button id="btn" on-tap="_fireParentEvent1">Fire 1!</button>
      <button id="btn" on-tap="_fireParentEvent2">Fire 2!</button>
      <button id="btn" on-tap="_fireParentEvent3">Fire 3!</button>
    </template>
  </dom-module>
  <dom-module id="child-element">
    <template>
      <style>
        :host {
          display: block;
        }
      </style>
      <span id="changeMe">Message</span>
    </template>
  </dom-module>

  <parent-element></parent-element>
  <script>
    (function registerElements() {
      Polymer({
        is: 'parent-element',
        listeners: {
          'event-two': '_attachToChild'
        },
        _attachToChild: function(e) {
          // the parent makes the child fire an event
          var childElement = Polymer.dom(this.root).querySelector('child-element');
          childElement.fire('event-two', e.detail);
        },
        _fireParentEvent1: function(e) {
          // the parent fires an event
          this.fire('event-one', {
            message: 'hello'
          });
        },
        _fireParentEvent2: function(e) {
          this.fire('event-two', {
            message: 'goodbye'
          });
        },
        _fireParentEvent3: function(e) {
          // the parent fires an event
          this.fire('event-three', {
            message: 'game over'
          });
        }
      });

      Polymer({
        is: 'child-element',
        listeners: {
          'event-two': '_handleEventTwo'
        },
        ready: function() {
          var parent = this.parentNode;

          // the child listens to the parent's event
          parent.addEventListener('event-one', function(e) {
            this.$.changeMe.innerHTML = e.detail.message;
          }.bind(this));

          // listen to the document level event (since events travel up)
          // but this option is difficult to control
          document.addEventListener('event-three', function(e) {
            this.$.changeMe.innerHTML = e.detail.message;
          }.bind(this));
        },
        _handleEventTwo: function(e) {
          this.$.changeMe.innerHTML = e.detail.message;
        }
      });
    })();
  </script>
</body>

</html>

With Polymer 1.2.4 as documented here we can use fire method options and force a child node (while still inside a parent element) to fire (and listen first of course) an event:

this.fire('test', {
    user: {
        name: 'Marios',
        gender: 'male'
    }
}, {
    node: Polymer.dom(this.root).querySelectorAll('my-child-element'),
    bubbles: false
});

We fired a custom event from an element but the emitter is the my-child-element so in there we can attach a listener in the listeners object. We also prevent the event bubbling so this event won't move upwards following the parents elements path. A typical listener could be:

Polymer({
    is: 'my-child-element',

    properties: {
        ...
    },
    listeners: {
        'test': '_myHandler'
    },
    _myHandler: function(e) {
        var user = e.detail.user;
        ...
    }
});
@arthur in the Polymer Slack site says:

Events tend to go up the DOM tree. Going down, you can use a data binding or invoke a method.

Polymer Slack Site

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论