2016-02-01 17 views
30

Ho un componente che funge da barra di ricerca. Può fare richieste API e fornire i risultati al resto dell'app tramite un @Output e EventEmitter ma voglio anche che una funzione vada nella direzione opposta. Il componente Barra di ricerca mantiene una cronologia delle sue ricerche e vorrei fornire un modo al componente principale di cancellare la cronologia. Il meglio che posso pensare è in qualche modo chiamare un metodo nella mia barra di ricerca da un componente genitore.Chiamare una funzione in un figlio Componente angolare2?

Il meglio che ho trovato (ma non sono stato in grado di implementare correttamente) è quello di provare a passare un EventEmitter nella mia barra di ricerca e il bambino si iscrive agli eventi del genitore. Il @Input non ha completato il binding al momento del costruttore, quindi è difficile farlo effettivamente.

Suppongo che potrei provare e memorizzare la cronologia nel componente padre, ma il motivo per cui la barra di ricerca è un componente è perché apparirà in più punti e questo non si adatta a Separation of Concerns quindi mi sembra meglio mantieni la cronologia nel componente della barra di ricerca.

Come può un componente padre chiamare una funzione su un componente figlio?

+0

Mettere la cronologia delle ricerche in un servizio e il vostro componente figlio possibile associare ai servizi istanza "cronologia" var. Il servizio può avere un chiaro che il genitore può chiamare. Solo un'idea Non ho ancora provato. –

+0

una bella lettura - http://learnangular2.com/viewChild/ –

risposta

30

Si scopre che posso inserire una variabile locale sul componente e avere accesso alle sue funzioni pubbliche. Cioè .:

<search-bar #SearchBar ...></search-bar> 
<button (click)='SearchBar.ClearHistory()' ...></button> 

A quanto pare la variabile locale si lega al componente e non il DOM come ho inizialmente pensato che ha fatto. Immagino di avere accesso a tutti i campi e le funzioni pubbliche.

+1

Questa è letteralmente la cosa migliore di sempre. Ben fatto. – Dave

+0

non solo, puoi anche passare SearchBar come parametro a una chiamata di funzione, e puoi usarlo se dichiari come "qualsiasi" senza dover usare il brutto e disordinato ViewChild;) – Ayyash

+0

Puoi anche gestire l'evento click in il componente genitore. Se usi ViewChild ('SearchBar') = SearchBar, puoi usare this.SearchBar.ClearHistory() sul ViewChild, per eseguire il metodo childs! – ant45de

34

È necessario sfruttare il @ViewChild decoratore per fare riferimento al componente figlio dal genitore a uno a iniezione:

import { Component, ViewChild } from 'angular2/core'; 

(...) 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <h1>My First Angular 2 App</h1> 
    <child></child> 
    <button (click)="submit()">Submit</button> 
    `, 
    directives:[App] 
}) 
export class AppComponent { 
    @ViewChild(SearchBar) searchBar:SearchBar; 

    (...) 

    someOtherMethod() { 
    this.searchBar.someMethod(); 
    } 
} 

Ecco la plunkr aggiornamento: http://plnkr.co/edit/mrVK2j3hJQ04n8vlXLXt?p=preview.

Si può notare che il @Query parametro di decoratore potrebbe anche essere utilizzato:

export class AppComponent { 
    constructor(@Query(SearchBar) children:QueryList<SearchBar>) { 
    this.childcmp = children.first(); 
    } 

    (...) 
} 

Spero che ti aiuta, Thierry

+1

Mi piace questo approccio. Il vantaggio aggiuntivo che ha sulla mia soluzione è che nel mio non posso accedere al SearchBar nel file di codice del mio componente genitore, posso solo accedervi nel mio codice template (che diventa rapidamente disordinato). –

+0

Questo è ottimo perché voglio richiamare automaticamente il metodo in base a un evento di componenti figlio diverso che viene generato in modo che il modo modello non mi si adatti. Tuttavia, se avessi 2 componenti SearchBar in questa pagina c'è un modo per specificare quale chiamare il metodo some di? – James

Problemi correlati