我有一个带有子元素的元素作为按钮。当我按下“输入”时在父元素的输入框中,我想触发子的_runNavigation方法。创建自定义触发器的最佳方法是什么,父级会向子元素触发事件?
我尝试在我的子元素中创建了一个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);
},
});
当文本框处于焦点时按下输入时触发事件:
<...>
<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});
}
}
虽然这会触发由子元素拾取的事件,但是这会导致&#39;不会运行因为&#39;这个&#39;现在是文件。我已经尝试将事件监听器更改为 this.addEventListener(&#39; fire&#39;,this._runNavigation); 将它添加到元素本身,但元素不会检测来自父元素的触发器。
答案 0 :(得分:4)
如果除了在Polymer元素中使用document.addEventListener
之外别无选择,则必须使用bind()
设置this._runNavigation
的上下文:
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 ...
要向儿童发送活动,您在致电fire()
时会设置几个选项。
fire(type, [detail], [options])
。触发自定义事件。options
对象可以包含以下属性:
node
。用于触发事件的节点(默认为此)。
bubbles
。该事件是否应该冒泡。默认为true。
cancelable
。是否可以使用preventDefault取消事件。默认为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
事件未冒泡到文档中(事件处理程序中未记录任何警告)。