2015-06-23 16 views

Trả lời

58

Bạn có thể lấy một tham chiếu đến một yếu tố sử dụng

@ViewChild('childComponent') child; 

nơi childComponent là một mẫu biến <some-elem #childComponent> `hoặc

@ViewChild(ComponentType) child; 

nơi ComponentType là loại một thành phần hoặc chỉ thị và sau đó trong ngAfterViewInit hoặc trình xử lý sự kiện, gọi child.someFunc().

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

Xem thêm get hold of an element in the template

+0

Tôi nghĩ cú pháp là' @ViewChild (ComponentName) con; 'và theo [tài liệu] (https://angular.io/docs/ts/latest/api/core/ViewChild-var.html) nó không có sẵn cho đến khi móc vòng đời 'ngAfterViewInit()'. –

+0

Tôi đã thử nó. Khi một chuỗi được truyền, nó tra cứu các biến mẫu với tên này, nếu không một thành phần hoặc chỉ thị của kiểu được truyền. "Bộ chọn" trong tài liệu hơi gây hiểu nhầm. –

+1

Cảm ơn bạn đã cập nhật. Tôi đã xem [mã nguồn cho ViewChild] (https://github.com/angular/angular/blob/2.0.0-beta.0/modules/angular2/src/core/metadata.ts#L1147-L1147), và nó nói "Hỗ trợ các tham số truy vấn giống như QueryMetadata, ngoại trừ con cháu." [QueryMetadata API doc] (https://angular.io/docs/ts/latest/api/core/QueryMetadata-class.html) giải thích tất cả các loại "bộ chọn" khác nhau được hỗ trợ. (Tìm công cụ này là một nỗi đau như vậy tại thời điểm này.) –

47

Cha mẹ và con có thể giao tiếp thông qua ràng buộc dữ liệu.

Ví dụ:

@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 tạo ra một tham chiếu đến thành phần trẻ và có thể được sử dụng trong mẫu hoặc được truyền cho hàm. Dữ liệu từ cấp độ gốc có thể được chuyển bởi ràng buộc [ ].

+0

Tôi đang làm điều gì đó sai. Khi tôi khai báo một biến như #f - rằng #f đề cập đến phần tử dom và khi tôi làm f.someMethodCall() tôi nhận được một lỗi vì phương thức đó không được định nghĩa trên phần tử đó. Bạn có biết những gì là sai? –

+2

@ PerHornshøj-Schierbeck, nếu không có thành phần/chỉ thị trên phần tử, biến mẫu cục bộ (ví dụ: '# f') đề cập đến chính phần tử đó. Có lẽ đó là vấn đề của bạn. –

+0

@ PerHornshøj-Schierbeck biến phải được khai báo trước khi sử dụng (bạn không thể đặt 'thành phần con' từ ví dụ như cuối cùng trong mẫu) –

13

Là một thành phần con trai

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

    data: number = 3; 

    constructor() { } 

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

} 

Có một thành phần cha

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

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

Trong mẫu của người cha

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

Giải pháp này chỉ hoạt động cho một cá thể <son></son> trong mẫu chính. Nếu bạn có nhiều hơn một cá thể chỉ hoạt động trong mẫu đầu tiên.

+1

Bạn chỉ có thể sử dụng '@ViewChildren()' để có được tất cả chúng. –

+0

Điều này đã lừa tôi! IntelliSense của tôi sẽ không đón các phương thức thành phần con khiến tôi tin rằng nó không thể nhìn thấy được! +1 – gudthing

0

Cách tốt nhất để truy cập thành phần con là @ViewChild.

Giả sử bạn có AppMainComponent với một ChildComponent lồng nhau từ ví dụ của bạn.

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

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

export class AppMainComponent {} 

Bạn muốn gọi phương thức rõ ràng từ ChildComponent của bạn.

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

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

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

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

Bạn có thể thực hiện nó bằng cách import lớp ChildComponent, ViewChild trang trí và vượt qua lớp thành phần trong nó như là một truy vấn. Bằng cách này, bạn sẽ có quyền truy cập vào giao diện ChildComponent được lưu trữ trong biến tùy chỉnh.Dưới đây là ví dụ:

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

Lưu ý! Chế độ xem con sẽ chỉ khả dụng sau ngAfterViewInit.

Trả lời sau khi Góc khởi tạo chế độ xem của thành phần và chế độ xem con. Được gọi một lần sau lần đầu tiên ngAfterContentChecked(). Móc chỉ có thành phần.

Nếu bạn muốn thực thi phương pháp một cách tự động, bạn cần thực hiện nó bên trong móc vòng đời này.

Bạn cũng có thể nhận được QueryList thành phần con thông qua trang trí ViewChildren.

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

... 

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

Danh sách truy vấn có thể rất hữu ích, ví dụ: bạn có thể đăng ký cho trẻ em thay đổi.

Cũng có thể tạo template reference variables và nhận quyền truy cập vào chúng thông qua trang trí ViewChild.

Các vấn đề liên quan