2017-03-07 2 views
1

Ich möchte ein Suchfeld in einer Komponente haben, die überall in der App platziert werden kann. Es kann auf jeder Vorlage oder in Komponenten verschachtelt erscheinen. Das Suchformular würde eine Benutzereingabe (Suchbegriff) akzeptieren und submit würde eine Suchaktion auslösen, die in eine Ergebnisvorlage übergeht.Ember: global verfügbare Suchkomponente (und Aktion)?

Scheint einfach genug, aber ich kann nicht herausfinden, wie man eine Aktion global verfügbar macht. Und wenn ich könnte, wie übergibt man den eingegebenen Begriff überhaupt an die Handlung? Es gibt erstaunlich wenig Informationen darüber, wie man Formulare mit Ember CLI behandelt.

Bis jetzt habe ich gerade ein reguläres Formular mit action = '/ results' eingereicht. Aber das ist offensichtlich das Nachladen der App.

Ich habe Messing mit einer Aktion in den Index-Controller wie folgt zu erstellen:

export default Ember.Controller.extend(defaultParams, { 
    term: '', 
    actions: { 
     keywordSearch() { 
      this.transitionToRoute('results', { queryParams: { q: this.get('term') }}); 
     } 
    } 
}); 

Dann eine Schließung Aktion auf meine Suchkomponente vorbei, die 2 tief aus dem Index Vorlage verschachtelt ist.

index.hbs:

{{index-search keywordSearch=(action "keywordSearch")}} 

index search.hbs (Komponente):

{{search-field keywordSearch=keywordSearch }} 

search-field.hbs (verschachtelte Komponente):

<form {{ action (action keywordSearch) on='submit' }}> 
{{ input value=term }} 
<button type="submit">Search</button> 
</form> 

Und das wird die Aktion ausführen, aber term wird nicht geliefert. Wie liefern Sie term zum Schließen?

Und ... muss ich die Aktion wirklich an jeden einzelnen Ort weiterleiten, an dem das Suchfeld in der App angezeigt wird, oder gibt es einen einfacheren Weg dazu?

Antwort

2

Anstatt Aktionen in allen Komponenten und Routen zu schreiben, können Sie einen Dienst für die Suche erstellen. Inject den Dienst in die Komponente und behandeln den Routenübergang von Service-Methode. Überprüfen Sie den folgenden Beispielcode,

Search-component.hbs

<form {{ action (action search) on='submit' }}> 
{{ input value=keyword }} 
<button type="submit">Search</button> 
</form> 

Search-component.js

export default Ember.Component.extend({ 

    globalSearch: Ember.inject.service('search'), 

    actions: { 
    search() { 
     const { keyword } = this.getProperties('keyword'); 
     this.get('globalSearch').showResults(keyword).then(() => { 
     alert('Success'); 
     }, (err) => { 
     alert('Error while searching: ' + err.responseText); 
     }); 
    } 
    } 

}); 

Service - app/services/Search.js

import Ember from 'ember'; 

export default Ember.Service.extend({ 

    init() { 
    this._super(...arguments); 
    }, 

    showResults(keyword) { 
    // write code for transition to search results route here 
    } 
}); 
+1

Schön! Viel vernünftiger Ansatz – tarponjargon

+0

+1. Nur ein zusätzlicher Vorschlag. Sie könnten den Dienst auch in 'app/services/global-search.js' umbenennen und Embers Ad-hoc-Service-Injektion ' globalSearch: Ember.inject.service() 'verwenden, was äquivalent zu 'globalSearch: Ember.inject' ist. Dienst ('globale Suche'), ' – Ariella

Verwandte Themen