2016-06-11 24 views
1

我有一個具有充當按鈕的子元素的元素。當我在父元素的輸入框中按'Enter'時,我想觸發孩子的_runNavigation方法。在父項將事件觸發到子元素時創建自定義觸發器的最佳方法是什麼?使用來自父函數的事件的子元素中的聚合物觸發函數

我試圖在我的子元素創建的事件監聽:

<...> 
<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); 將它添加到元素本身,但然後該元素不檢測父元素的觸發器。

回答

4

如果你沒有其他選擇,只能使用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

正如你可能已經猜到,聚合物提供了火子元素上的事件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

+0

謝謝!我不知道消防呼叫包含了包含節點的能力! – Tykin

+0

@Tykin,沒問題:) – tony19