子元素中的聚合物触发器函数使用来自父函数的事件

时间:2016-06-11 18:47:31

标签: javascript html dom polymer polymer-1.0

我有一个带有子元素的元素作为按钮。当我按下“输入”时在父元素的输入框中,我想触发子的_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); 将它添加到元素本身,但元素不会检测来自父元素的触发器。

1 个答案:

答案 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>

codepen

正如您可能已经猜到的那样,Polymer提供了用于在子元素上触发事件的API ...

要向儿童发送活动,您在致电fire()时会设置几个选项。

  

fire(type, [detail], [options])。触发自定义事件。 options对象可以包含以下属性:

     
      
  • node。用于触发事件的节点(默认为此)。

  •   
  • bubbles。该事件是否应该冒泡。默认为true。

  •   
  • cancelable。是否可以使用preventDefault取消事件。默认为false。

  •   

在您的情况下,bubblesnode选项会很有用:

this.fire('fire', { searchQuery: this.searchQuery }, { bubbles:false, node: this.$.searchButton });

然后,在您的search-button元素中,您将使用:

this.addEventListener('fire', this._runNavigation); // bind() not necessary here

在此演示中请注意,fire事件未冒泡到文档中(事件处理程序中未记录任何警告)。

codepen