【问题标题】:Polymer trigger function in child element using event from parent function使用来自父函数的事件的子元素中的聚合物触发函数
【发布时间】:2016-06-11 18:47:31
【问题描述】:

我有一个带有子元素的元素,它充当按钮。当我在父元素的输入框中按“Enter”时,我想触发子元素的 _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}); 
    }
}

虽然这将触发由子元素拾取的事件,但“this.navigate”将不会运行,因为“this”现在是文档。我尝试将事件侦听器更改为 this.addEventListener('fire', this._runNavigation); 将其添加到元素本身,但随后该元素未检测到来自父元素的触发器。

【问题讨论】:

    标签: javascript html dom polymer polymer-1.0


    【解决方案1】:

    如果您别无选择,只能在 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>
    

    codepen

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

    要向孩子分派事件,您需要在调用 fire() 时设置几个选项。

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

    • node。触发事件的节点(默认为 this)。

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

    • 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 事件不会冒泡到文档中(事件处理程序中没有记录警告)。

    codepen

    【讨论】:

    • 谢谢!我不知道火灾呼叫包括包含节点的能力!
    • @Tykin,没问题 :)
    猜你喜欢
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 2013-12-28
    相关资源
    最近更新 更多