2015-06-23 11 views

risposta

58

È possibile ottenere un riferimento a un elemento utilizzando

@ViewChild('childComponent') child; 

dove childComponent è una variabile di modello <some-elem #childComponent> `o

@ViewChild(ComponentType) child; 

dove ComponentType è il tipo di un componente o di una direttiva e poi in ngAfterViewInit o un gestore di eventi chiama child.someFunc().

ngAfterViewInit() { 
    console.log(this.child); 
} 

Vedi anche get hold of an element in the template

+0

Penso che la sintassi sia' @ViewChild (ComponentName) child; 'e secondo [i documenti] (https://angular.io/docs/ts/latest/api/core/ViewChild-var.html) non è disponibile fino all'hook del ciclo di vita 'ngAfterViewInit()'. –

+0

L'ho provato. Quando viene passata una stringa, cerca le variabili del template con questo nome, altrimenti un componente o una direttiva del tipo passato. "Selector" nei documenti è un po 'fuorviante. –

+1

Grazie per l'aggiornamento. Ho esaminato il [codice sorgente per ViewChild] (https://github.com/angular/angular/blob/2.0.0-beta.0/modules/angular2/src/core/metadata.ts#L1147-L1147), e dice "Supporta gli stessi parametri di interrogazione di QueryMetadata, eccetto i discendenti." Il [QueryMetadata API doc] (https://angular.io/docs/ts/latest/api/core/QueryMetadata-class.html) spiega tutti i diversi tipi di "selettori" che sono supportati. (Trovare questa roba è così doloroso al momento.) –

47

Padre e figlio possono comunicare tramite associazione dati.

Esempio:

@Component({ 
    selector: 'child-component', 
    inputs: ['bar'], 
    template: `"{{ bar }}" in child, counter {{ n }}` 
}) 
class ChildComponent{ 
    constructor() { 
     this.n = 0; 
    } 
    inc() { 
     this.n++; 
    } 
} 

@Component({ 
    selector: 'my-app', 
    template: ` 
     <child-component #f [bar]="bar"></child-component><br> 
     <button (click)="f.inc()">call child func</button> 
     <button (click)="bar = 'different'">change parent var</button> 
    `, 
    directives: [ChildComponent] 
}) 
class AppComponent { 
    constructor() { 
     this.bar = 'parent var'; 
    } 
} 

bootstrap(AppComponent); 

Demo

#f crea un riferimento al componente figlio e può essere utilizzato in modello o passato alla funzione. I dati dal genitore possono essere passati dal binding [ ].

+0

Sto facendo qualcosa di sbagliato. Quando dichiaro una variabile come #f - che #f si riferisce all'elemento dom e quando faccio f.someMethodCall() ottengo un errore perché quel metodo non è definito su quell'elemento. Sai cosa c'è che non va? –

+2

@ PerHornshøj-Schierbeck, se non ci sono componenti/direttive sull'elemento, la variabile di modello locale (ad esempio, '# f ') fa riferimento all'elemento stesso. Forse questo è il tuo problema. –

+0

@ PerHornshøj-Schierbeck la variabile deve essere dichiarata prima del suo utilizzo (non è possibile inserire 'child-component' dall'esempio come ultimo nel modello) –

13

Essendo un componente figlio

@Component({ 
    // configuration 
    template: `{{data}}`, 
    // more configuration 
}) 
export class Son { 

    data: number = 3; 

    constructor() { } 

    updateData(data:number) { 
    this.data = data; 
    } 

} 

Avere un componente padre

@Component({ 
    // configuration 
}) 
export class Parent { 
    @ViewChild(Son) mySon: Son; 

    incrementSonBy5() { 
    this.mySon.updateData(this.mySon.data + 5); 
    } 
} 

Nel modello del padre

<son></son> 
<button (click)="incrementSonBy5()">Increment son by 5</button> 

Questa soluzione funziona solo per un'istanza <son></son> nel modello principale. Se hai più di un'istanza funzionerà solo nel primo modello.

+1

Puoi semplicemente usare '@ViewChildren()' per ottenerli tutti. –

+0

Questo mi ha ingannato! Il mio intellisenso non avrebbe raccolto i metodi dei componenti del bambino che mi portarono a credere che non fosse visibile! +1 – gudthing

0

Il modo migliore per accedere a un componente figlio è @ViewChild.

Supponiamo che tu abbia AppMainComponent con un componente figlio nidificato dal tuo esempio.

// app-main.component.ts 
import { Component } from '@angular/core'; 

@Component({ 
    selector: 'app-main', 
    template: ` 
     <child-component /> 
    ` 
}) 

export class AppMainComponent {} 

Si desidera richiamare un metodo chiaro da ChildComponent.

// child.component.ts 
import { Component } from '@angular/core'; 

@Component({ 
    selector: 'child-component', 
    template: '{{ greeting }}' 
}) 

class ChildComponent { 
    greeting: String = 'Hello World!'; 

    clear() { 
     this.greeting = null; 
    } 
} 

Si può realizzare importando la classe ChildComponent, ViewChild decoratore e passare di classe del componente in esso come una query. In questo modo, avresti accesso all'interfaccia di ChildComponent memorizzata nella variabile personalizzata.Ecco un esempio:

// app-main.component.ts 
import { Component, ViewChild } from '@angular/core'; 
import { ChildComponent } from './components/child/child.component'; 

@Component({ 
    selector: 'app-main', 
    template: ` 
     <child-component /> 
    ` 
}) 

class ChildComponent { 
    @ViewChild(ChildComponent) 
    child: ChildComponent; 

    clearChild() { 
     this.child.clear(); 
    } 
} 

Avviso! La visualizzazione figlio diventa disponibile solo dopo ngAfterViewInit.

Risposta dopo Angolare inizializza le viste del componente e le viste secondarie. Chiamato una volta dopo il primo ngAfterContentChecked(). Un hook solo componente.

Se si desidera eseguire il metodo automaticamente, è necessario farlo all'interno di questo hook ciclo di vita.

È inoltre possibile ottenere un QueryList di componenti figlio tramite il decoratore ViewChildren.

import { Component, ViewChildren, QueryList } from '@angular/core'; 
import { ChildComponent } from './components/child/child.component'; 

... 

@ViewChildren(ChildComponent) 
children: QueryList<ChildComponent>; 

QueryList potrebbe essere molto utile, ad es. puoi iscriverti alle modifiche dei bambini.

È anche possibile creare template reference variables e accedervi tramite il decoratore ViewChild.