2016-10-26 6 views
5

Я искал причину такого поведения, значение свойства Input() в дочернем компоненте «Параметр» не обновляется в нужное время, мне нужно используйте обновленное значение для вызова службы в качестве параметра. Нажав кнопку «Обновить дочернее значение», сначала отображается LOG B (со старым значением), после чего отображается LOG A (LOG A находится в настройщике свойства).свойство ввода viewchild не обновляется при необходимости угловой 2

родительского компонент

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

ребенок компонент

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

желаемое поведение должны иметь первое значение паров обновляются, а затем использовать это значение в качестве параметра на службе. LOG A затем LOG B

ответ

3

Использование @Input() подразумевает, что вы используете механизм Angular2 для распространения изменений значений, а это означает, что вы не должны ожидать, что ваши изменения вступят в силу немедленно. Фактически, ваш this.parentParam = 9; будет проходить весь цикл Angular2, чтобы обновить param вашего ребенка, и функция showParam() всегда будет выполнена первой.

Для достижения этой задачи, у вас есть 2 варианта:

1) Добавить параметр прямо в showParam, как:

// 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) Рычаги ngOnChanges на вашем Child компоненте. Эта функция будет вызываться Angular2 каждый раз, когда происходит изменение любого @Input. Однако, если у вас более одного ввода, это может быть проблематично.

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

поблагодарить Вас за sugestions @ HarryNinh, я пытался использовать методы ChangeDetectorRef markForCheck и detectChanges в методе showParam. showParam - просто пример, реальное использование: переменная parentParam будет отправляться как параметр при вызове службы. означает, что любой обмен на parentParam не означает, что нам нужно немедленно позвонить в службу. Я в настоящее время ищу $ digest, как в угловом 1.x, даже зная, что это делается «автоматически» Вы думаете, что я на правильном пути? – destined

1

Я думаю, что это лучший ответ, чем текущий принятый ответ:

Angular2 + способом достижения этой цели является использованием ngOnChanges жизненного цикла крюка:

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; 
    } 
}