2016-06-11 2 views
1

Ich habe ein Element mit einem Kind-Element, das als Schaltfläche fungiert. Wenn ich im Eingabefeld des übergeordneten Elements die Eingabetaste drücke, möchte ich die _runNavigation-Methode des Kindes auslösen. Was ist der beste Weg, einen benutzerdefinierten Auslöser zu erstellen, bei dem der Elternteil ein Ereignis an das Kindelement absetzt?Polymer-Trigger-Funktion in Kind-Element mit Ereignis von Eltern-Funktion

Ich habe versucht, ein Eventlistener in meinem Kind-Element erstellt:

<...> 
<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); 
}, 

}); 

und Brennen des Ereignisses, wenn enter gedrückt wird, wenn das Textfeld im Fokus ist:

<...> 
    <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}); 
    } 
} 

Während dies ein Feuer Ereignis, das vom Kindelement übernommen wird, 'this.navigate' wird nicht ausgeführt, weil 'this' jetzt das Dokument ist. Ich habe versucht, den Ereignis-Listener auf this.addEventListener ('fire', this._runNavigation) zu ändern; , um es dem Element selbst hinzuzufügen, aber dann erkennt das Element den Auslöser nicht vom übergeordneten Element.

ready: function() { 
    document.addEventListener('fire', this._runNavigation.bind(this)); // avoid! 
} 

Während dies in Ihrem Beispiel funktionieren würde, es hört:

Antwort

4

Wenn Sie aber keine andere Wahl haben document.addEventListener aus Ihrem Polymer Elemente zu verwenden, würden Sie den Kontext this._runNavigation mit bind() setzen müssen zu dem fire Ereignis für das gesamte Dokument, wenn also ein anderes Element außerhalb der Hierarchie Ihres Formulars dieses Ereignis ausgelöst hat, würde es den Handler Ihres Elements auslösen, was unerwünscht sein könnte. Zum Beispiel:

<x-form></x-form> <!-- listens to all 'fire' events --> 

    <script> 
    setTimeout(function() { 
     // unrelated 'fire' 
     document.dispatchEvent(new Event('fire')); 
    }, 1000); 
    </script> 

codepen

Wie Sie vielleicht erraten haben könnte, bietet Polymer die API ein Ereignis auf ein Kind Element Feuer ...

ein Ereignis, um ein Kind zu versenden , würden Sie ein paar Optionen beim Aufruf fire() festlegen.

fire(type, [detail], [options]). Feuert ein benutzerdefiniertes Ereignis ab. Das options Objekt kann die folgenden Eigenschaften enthalten:

  • node. Knoten zum Auslösen des Ereignisses (standardmäßig).

  • bubbles. Ob die Veranstaltung platzen soll. Der Standardwert ist wahr.

  • cancelable. Ob das Ereignis mit preventDefault abgebrochen werden kann. Der Standardwert ist false.

In Ihrem Fall die bubbles und node Optionen nützlich wäre:

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

Dann in Ihrem search-button Element, dann würden Sie verwenden:

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

Hinweis in Diese Demo, dass das Ereignis fire nicht auf das Dokument (keine Warnung eingeloggten Ereignishandler) Blase.

codepen

+0

Dank! Ich hatte keine Ahnung, dass der Feueranruf die Fähigkeit beinhaltete, den Knoten einzuschließen! – Tykin

+0

@Tykin, Kein Problem :) – tony19

Verwandte Themen