使用来自父函数的事件的子元素中的聚合物触发函数
Polymer trigger function in child element using event from parent function
我有一个元素,它的子元素充当按钮。当我在父元素的输入框中按下 'Enter' 时,我想触发子元素的 _运行Navigation 方法。创建父级向子元素触发事件的自定义触发器的最佳方法是什么?
我已经尝试在我的子元素中创建一个 EventListener:
<...>
<button type="button" class="btn btn-success" on-click="_runNavigation">{{result}}</button
<...>
Polymer({
is: 'search-button',
properties: {
searchQuery: {
type: String,
}
},
ready : function (){
document.addEventListener('fire', this._runNavigation);
},
navigate: function(url) {
var win = window.open(url, '_blank');
if (win != null) {
win.focus();
}
},
_runNavigation: function() {
var text = this.searchQuery;
this.navigate("https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=" + text);
},
});
并在文本框处于焦点状态时按下 enter 时触发事件:
<...>
<input id="input" type="text" value="{{searchQuery::input}}" on-keydown="checkForEnter" on-change="_inputChanged" class="form-control" placeholder="Search">
<...>
checkForEnter: function(e) {
// check if 'enter' was pressed
if (e.keyCode === 13) {
// enter pressed!
console.log("ENTER!");
this.fire('fire', {searchQuery: this.searchQuery});
}
}
虽然这会触发一个由子元素拾取的事件,但 'this.navigate' 不会 运行 因为 'this' 现在是文档。我尝试将事件侦听器更改为
this.addEventListener('fire', this._runNavigation);
将其添加到元素本身,但随后元素未检测到来自父元素的触发器。
如果您别无选择,只能在 Polymer 元素中使用 document.addEventListener
,则必须将 this._runNavigation
的上下文设置为 bind()
:
ready: function() {
document.addEventListener('fire', this._runNavigation.bind(this)); // avoid!
}
虽然这在您的示例中可行,但它会在整个文档 上侦听 fire
事件 ,因此如果触发了表单层次结构之外的任何其他元素该事件,它会触发您的元素的处理程序,这可能是不可取的。例如:
<x-form></x-form> <!-- listens to all 'fire' events -->
<script>
setTimeout(function() {
// unrelated 'fire'
document.dispatchEvent(new Event('fire'));
}, 1000);
</script>
您可能已经猜到了,Polymer 提供了 API 在 child 元素上触发事件...
要将事件分派给 child,您需要在调用 fire()
时设置几个选项。
fire(type, [detail], [options])
. Fires a custom event. The options
object can contain the following properties:
node
. Node to fire the event on (defaults to this).
bubbles
. Whether the event should bubble. Defaults to true.
cancelable
. Whether the event can be canceled with preventDefault. Defaults to false.
在您的情况下,bubbles
和 node
选项会很有用:
this.fire('fire', { searchQuery: this.searchQuery }, { bubbles:false, node: this.$.searchButton });
然后,在您的 search-button
元素中,您将使用:
this.addEventListener('fire', this._runNavigation); // bind() not necessary here
请注意,在此演示中,fire
事件不会冒泡到文档(事件处理程序中没有记录警告)。
我有一个元素,它的子元素充当按钮。当我在父元素的输入框中按下 'Enter' 时,我想触发子元素的 _运行Navigation 方法。创建父级向子元素触发事件的自定义触发器的最佳方法是什么?
我已经尝试在我的子元素中创建一个 EventListener:
<...>
<button type="button" class="btn btn-success" on-click="_runNavigation">{{result}}</button
<...>
Polymer({
is: 'search-button',
properties: {
searchQuery: {
type: String,
}
},
ready : function (){
document.addEventListener('fire', this._runNavigation);
},
navigate: function(url) {
var win = window.open(url, '_blank');
if (win != null) {
win.focus();
}
},
_runNavigation: function() {
var text = this.searchQuery;
this.navigate("https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=" + text);
},
});
并在文本框处于焦点状态时按下 enter 时触发事件:
<...>
<input id="input" type="text" value="{{searchQuery::input}}" on-keydown="checkForEnter" on-change="_inputChanged" class="form-control" placeholder="Search">
<...>
checkForEnter: function(e) {
// check if 'enter' was pressed
if (e.keyCode === 13) {
// enter pressed!
console.log("ENTER!");
this.fire('fire', {searchQuery: this.searchQuery});
}
}
虽然这会触发一个由子元素拾取的事件,但 'this.navigate' 不会 运行 因为 'this' 现在是文档。我尝试将事件侦听器更改为 this.addEventListener('fire', this._runNavigation); 将其添加到元素本身,但随后元素未检测到来自父元素的触发器。
如果您别无选择,只能在 Polymer 元素中使用 document.addEventListener
,则必须将 this._runNavigation
的上下文设置为 bind()
:
ready: function() {
document.addEventListener('fire', this._runNavigation.bind(this)); // avoid!
}
虽然这在您的示例中可行,但它会在整个文档 上侦听 fire
事件 ,因此如果触发了表单层次结构之外的任何其他元素该事件,它会触发您的元素的处理程序,这可能是不可取的。例如:
<x-form></x-form> <!-- listens to all 'fire' events -->
<script>
setTimeout(function() {
// unrelated 'fire'
document.dispatchEvent(new Event('fire'));
}, 1000);
</script>
您可能已经猜到了,Polymer 提供了 API 在 child 元素上触发事件...
要将事件分派给 child,您需要在调用 fire()
时设置几个选项。
fire(type, [detail], [options])
. Fires a custom event. Theoptions
object can contain the following properties:
node
. Node to fire the event on (defaults to this).
bubbles
. Whether the event should bubble. Defaults to true.
cancelable
. Whether the event can be canceled with preventDefault. Defaults to false.
在您的情况下,bubbles
和 node
选项会很有用:
this.fire('fire', { searchQuery: this.searchQuery }, { bubbles:false, node: this.$.searchButton });
然后,在您的 search-button
元素中,您将使用:
this.addEventListener('fire', this._runNavigation); // bind() not necessary here
请注意,在此演示中,fire
事件不会冒泡到文档(事件处理程序中没有记录警告)。