2016-10-26 17 views
5

Tôi đã tìm kiếm một số lý do của hành vi này, giá trị của thuộc tính Input() trong thành phần con 'Param' không được cập nhật vào đúng thời điểm, tôi cần sử dụng giá trị được cập nhật để gọi một dịch vụ làm tham số. Bằng cách nhấp vào nút 'cập nhật giá trị con', LOG B được hiển thị đầu tiên (với giá trị cũ) sau đó LOG A được hiển thị (LOG A nó nằm trong setter của thuộc tính).thuộc tính đầu vào viewchild không được cập nhật khi cần góc 2

thành phần thành phần Chánh

@Component({ 
    selector: 'parent', 
    template: ` 
    <child #child [param]="parentParam"></child> 
    <button (click)="updateChildValue()">Update child value</button> 
`}) 
export class Parent { 
    @ViewChild('child') child: Child; 
    public parentParam: number; 

    public updateChildValue() { 
    this.parentParam = 9; 
    this.child.showParam(); 
    } 
} 

trẻ

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

export class Child { 

    private _param: number; 

    public get param() : number { 
     return this._param; 
    } 

    @Input('param') 
    public set param(v : number) { 
     this._param = v; 
     console.log('LOG A'); 
     console.log(this.param);   
    } 

    public showParam() { 
     console.log('LOG B'); 
     console.log(this.param); 
     //I need to call a service using the latest value of param here... 
    } 
} 

Các hành vi mong muốn là phải có đầu tiên giá trị của param cập nhật và sau đó sử dụng giá trị đó như một tham số vào một dịch vụ. LOG A rồi LOG B

Trả lời

3

Sử dụng @Input() ngụ ý bạn đang dựa vào cơ chế Angular2 để truyền bá thay đổi giá trị, có nghĩa là bạn không nên mong đợi những thay đổi của mình có hiệu lực ngay lập tức. Thực tế, this.parentParam = 9; của bạn sẽ trải qua toàn bộ vòng lặp Angular2 để cập nhật param của con bạn và chức năng showParam() sẽ luôn được thực hiện trước tiên.

Để đạt được nhiệm vụ của bạn, bạn có 2 lựa chọn:

1) Thêm tham số trực tiếp đến showParam của bạn, như trong:

// child component 
public showParam(newVal: number) { 
    this._param = newVal; 
    // do your service call here 
} 

// parent component 
public updateChildValue() 
{ 
    this.parentParam = 9; 
    this.child.showParam(9); 
} 

2) Đòn bẩy ngOnChanges trên phần Child của bạn. Hàm này sẽ được Angular2 gọi mỗi khi có thay đổi đối với bất kỳ @Input nào. Tuy nhiên, nếu bạn có nhiều hơn 1 đầu vào, điều này có thể có vấn đề.

ngOnChanges(changes) { 
    console.log(this.param); // new value updated 
} 
+0

cảm ơn bạn đã sugestions của bạn @ HarryNinh, tôi đã cố gắng sử dụng các phương thức ChangeDetectorRef markForCheck và detectChanges trong phương thức showParam. showParam chỉ là một ví dụ, sử dụng thực: biến parentParam sẽ được gửi như một tham số trong một cuộc gọi đến một dịch vụ. nghĩa là anychange trên parentParam không có nghĩa là chúng ta cần gọi dịch vụ ngay lập tức. Tôi hiện đang tìm kiếm một $ digest như trong góc 1.x ngay cả khi biết điều này được thực hiện 'tự động' bạn có nghĩ rằng tôi đang đi đúng hướng không? – destined

1

Tôi nghĩ rằng đây là một câu trả lời tốt hơn so với câu trả lời chấp nhận hiện tại:

Các Angular2 + cách để đạt được điều này bằng cách sử dụng các móc ngOnChanges vòng đời:

Parent component: 


@Component({ 
    selector: 'parent', 
    template: ` 
    <child #child [param]="parentParam"></child> 
    <button (click)="updateChildValue()">Update child value</button> 
`}) 
export class Parent { 
    @ViewChild('child') child: Child; 
    public parentParam: number; 

    public updateChildValue() { 
    this.parentParam = 9; 
    this.child.showParam(); 
    } 
} 

the child component: 

import { OnChanges, SimpleChanges, SimpleChange } from '@angular/core' 

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

export class Child implements OnChanges { 

    @Input() param: number; 



    public showParam() { 
     console.log('LOG B'); 
     console.log(this.param); 
     //I need to call a service using the latest value of param here... 
    } 

    ngOnChanges(changes: SimpleChanges) { 
    const c: SimpleChange = changes.param; 
    this.param = c; 
    } 
} 
Các vấn đề liên quan