2015-06-23 3 views

ответ

58

Вы можете получить ссылку на элемент с помощью

@ViewChild('childComponent') child; 

где childComponent является переменным шаблоном <some-elem #childComponent> `или

@ViewChild(ComponentType) child; 

где ComponentType типа компонента или директив, а затем в ngAfterViewInit или обработчиками событий child.someFunc().

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

get hold of an element in the template Смотрите также

+0

Я думаю, что синтаксис - это '@ViewChild (имя_компьютера) child; в соответствии с [docs] (https://angular.io/docs/ts/latest/api/core/ViewChild-var.html) он недоступен до «ngAfterViewInit()» цикла жизненного цикла. –

+0

Я попробовал. Когда строка передается, она ищет переменные шаблона с этим именем, в противном случае - компонент или директиву прошедшего типа. «Селектор» в документах немного вводит в заблуждение. –

+1

Спасибо за обновление. Я посмотрел на [исходный код для ViewChild] (https://github.com/angular/angular/blob/2.0.0-beta.0/modules/angular2/src/core/metadata.ts#L1147-L1147), и он говорит: «Поддерживает те же параметры запроса, что и QueryMetadata, кроме потомков». В [QueryMetadata API doc] (https://angular.io/docs/ts/latest/api/core/QueryMetadata-class.html) объясняются все поддерживаемые типы «селекторов». (Нахождение этого материала - такая боль в данный момент.) –

47

Родитель и ребенок могут связываться через привязку данных.

Пример:

@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 создает ссылку на компонент ребенка и может быть использован в шаблоне или передается функционировать. Данные от родителя могут быть переданы посредством привязки [ ].

+0

Я делаю что-то неправильно. Когда я объявляю переменную типа #f - что #f ссылается на элемент dom, и когда я делаю f.someMethodCall(), я получаю ошибку, потому что этот метод не определен для этого элемента. Вы знаете, что не так? –

+2

@ PerHornshøj-Schierbeck, если на элементе нет компонента/директивы, локальная переменная шаблона (например, '# f') относится к самому элементу. Возможно, это твоя проблема. –

+0

@ PerHornshøj-Schierbeck переменная должна быть объявлена ​​до ее использования (вы не можете поместить «дочерний компонент» из примера как последний в шаблоне) –

13

Являясь составной SON

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

    data: number = 3; 

    constructor() { } 

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

} 

Имея отец компонент

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

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

В шаблоне отца

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

Это решение работает только для одного экземпляра <son></son> в родительском шаблоне. Если у вас несколько экземпляров, они будут работать только в первом шаблоне.

+1

Вы можете просто использовать '@ViewChildren()', чтобы получить все из них. –

+0

Это обмануло меня! Мой intellisense не подобрал бы методы детских компонентов, заставив меня поверить, что это не было видно! +1 – gudthing

0

Лучший способ доступа к дочернему компоненту - @ViewChild.

Предположим, у вас есть AppMainComponent с вложенным ChildComponent из вашего примера.

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

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

export class AppMainComponent {} 

Вы хотите вывести чистый метод из вашего 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; 
    } 
} 

Вы можете сделать это путем импорта класс ChildComponent, ViewChild декоратора и передать класс компонента в нем в качестве запроса. Таким образом, у вас будет доступ к интерфейсу ChildComponent, сохраненному в пользовательской переменной.Вот пример:

// 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(); 
    } 
} 

Внимание! Вид ребенка становится доступным только после ngAfterViewInit.

Respond after Угловой инициализирует виды компонентов и виды детей. Вызывается один раз после первого ngAfterContentChecked(). Компонентный крючок.

Если вы хотите выполнить метод автоматически, вам нужно сделать это внутри этого цикла жизненного цикла.

Вы также можете получить QueryList детских компонентов через ViewChildren декоратор.

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

... 

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

QueryList может быть очень полезным, например. вы можете подписаться на детские изменения.

Также можно создать template reference variables и получить доступ к ним через декоратор ViewChild.

Смежные вопросы