javascript - 使用父函数中的事件在子元素中聚合触发函数

标签 javascript html dom polymer polymer-1.0

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

});

当文本框处于焦点状态时按下 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 ,则必须使用 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...

要将事件分派(dispatch)给子级,您需要在调用 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.

就您而言,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

关于javascript - 使用父函数中的事件在子元素中聚合触发函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37767376/

相关文章:

javascript - 从对象数据生成表

javascript - 使用纯 JS 在 jQuery 中像 wrap() 函数一样包装元素

javascript - 如何在 html 表格中启用新添加的行可点击?

javascript - 为什么 PhantomJS 不抓取它重定向到的页面?

javascript - 如何单击基于 ref 属性的按钮?

html - 如何防止图像/ block 换行?

Javascript 脚本不会登录到浏览器控制台

javascript - Jasmine 与 helper

javascript - 需要添加一个类来隐藏和显示激活后的元素

javascript - IE 因在闭包中引用 DOM 元素而导致内存泄漏?