2016-10-26 14 views
5

Szukałem jakiegoś powodu tego zachowania, wartość właściwości Input() w komponencie potomnym "Param" nie została zaktualizowana we właściwym czasie, muszę użyj zaktualizowanej wartości, aby wywołać usługę jako parametr. Kliknięcie przycisku "zaktualizuj wartość podrzędną" powoduje wyświetlenie LOG B (ze starą wartością) po wyświetleniu LOG ​​A (LOG A w ustawieniu właściwości).Właściwość wejściowa viewchild nie jest aktualizowana w razie potrzeby 2

Komponent nadrzędna

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

dziecko

@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... 
    } 
} 

pożądane zachowanie jest najpierw mieć wartość param zaktualizowaną, a następnie użyć tej wartości jako parametru na usługi. LOG A następnie LOG B

Odpowiedz

3

Zastosowanie @Input() oznacza, że ​​polegasz na mechanizmie Angular2, aby propagować zmiany wartości, co oznacza, że ​​nie powinieneś oczekiwać, że twoje zmiany odniosą natychmiastowy skutek. W rzeczywistości Twój this.parentParam = 9; przejdzie cały cykl Angular2, aby zaktualizować param dziecka, a funkcja showParam() zawsze będzie wykonywana jako pierwsza.

Aby osiągnąć swoje zadanie, masz 2 możliwości:

1) Dodaj parametr bezpośrednio do showParam, na przykład:

// 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) Dźwignia ngOnChanges dotyczące komponentu Child. Ta funkcja będzie wywoływana przez Angular2 za każdym razem, gdy nastąpi zmiana w dowolnym @Input. Jeśli jednak masz więcej niż 1 wejście, może to być problematyczne.

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

dziękuję za sugestie @ HarryNinh, próbowałem użyć metod ChangeDetectorRef markForCheck i detectChanges w metodzie showParam. showParam to tylko przykład, rzeczywiste użycie: zmienna parentParam zostanie wysłana jako parametr w wywołaniu usługi. znaczenie anychange na parentParam nie oznacza, że ​​musimy natychmiast zadzwonić do serwisu. Obecnie szukam $ digest jak w kanciastym 1.x nawet wiedząc, że robi się "automatycznie" czy myślisz, że jestem we właściwy sposób? – destined

1

myślę, że jest to lepsze rozwiązanie niż obecne zaakceptowanej odpowiedzi:

Angular2 + sposobem osiągnięcia tego celu jest za pomocą haka ngOnChanges cyklem życia:

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; 
    } 
} 
Powiązane problemy