Polymer 1.0:如何在不使用 <iron-signals> 的情况下将事件传递给 child-node 元素?
Polymer 1.0: How to pass an event to a child-node element without using <iron-signals>?
建议使用 <iron-signals>
将事件沿 DOM 树传播到自定义元素。
下面,我问一个不同的问题。
问题
How do I:
- pass an event down to a direct child node (custom element)
- from a parent (custom element)
- without using
<iron-signals>
?
代码
这就是我目前所拥有的。但是没用。
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>
Polymer Slack 网站上的@arthur 说:
Events tend to go up the DOM tree. Going down, you can use a data binding or invoke a method.
你绝对可以。没有 iron-signals
你有三个选项(我目前知道的):
- 获取 parent 并让 child 将事件侦听器附加到 parent
- parent 可以让 child 触发相同的事件
- 您提到事件只会上升。然后,您可以让 child 元素监听
document
触发该事件(但我认为这很糟糕)
这是一个例子
<!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>
使用 Polymer 1.2.4 记录 here 我们可以使用 fire
方法选项并强制子节点(同时仍在父元素内)触发(当然首先监听)一个事件:
this.fire('test', {
user: {
name: 'Marios',
gender: 'male'
}
}, {
node: Polymer.dom(this.root).querySelectorAll('my-child-element'),
bubbles: false
});
我们从一个元素触发了一个自定义事件,但发射器是 my-child-element
,所以我们可以在 listeners
对象中附加一个侦听器。我们还防止事件冒泡,因此该事件不会沿着父元素路径向上移动。典型的听众可能是:
Polymer({
is: 'my-child-element',
properties: {
...
},
listeners: {
'test': '_myHandler'
},
_myHandler: function(e) {
var user = e.detail.user;
...
}
});
<iron-signals>
将事件沿 DOM 树传播到自定义元素。
下面,我问一个不同的问题。
问题
How do I:
- pass an event down to a direct child node (custom element)
- from a parent (custom element)
- without using
<iron-signals>
?
代码
这就是我目前所拥有的。但是没用。
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>
Events tend to go up the DOM tree. Going down, you can use a data binding or invoke a method.
你绝对可以。没有 iron-signals
你有三个选项(我目前知道的):
- 获取 parent 并让 child 将事件侦听器附加到 parent
- parent 可以让 child 触发相同的事件
- 您提到事件只会上升。然后,您可以让 child 元素监听
document
触发该事件(但我认为这很糟糕)
这是一个例子
<!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>
使用 Polymer 1.2.4 记录 here 我们可以使用 fire
方法选项并强制子节点(同时仍在父元素内)触发(当然首先监听)一个事件:
this.fire('test', {
user: {
name: 'Marios',
gender: 'male'
}
}, {
node: Polymer.dom(this.root).querySelectorAll('my-child-element'),
bubbles: false
});
我们从一个元素触发了一个自定义事件,但发射器是 my-child-element
,所以我们可以在 listeners
对象中附加一个侦听器。我们还防止事件冒泡,因此该事件不会沿着父元素路径向上移动。典型的听众可能是:
Polymer({
is: 'my-child-element',
properties: {
...
},
listeners: {
'test': '_myHandler'
},
_myHandler: function(e) {
var user = e.detail.user;
...
}
});