2016-10-03 52 views
4

我遇到了使用Angular 2 ngModel綁定的問題。 plnkrngModel綁定在Angular 2的OnInit中爲null

如果我使用ngModel將值綁定到子組件,則該值不會填充到子組件的OnInit函數中。所以如果我綁定到一個屬性調用「boundName」,我嘗試訪問OnInit中的它,它將爲空。但是,如果我綁定到父控件中不使用ngModel但輸入參數相同的值,可以在OnInit函數中訪問該值。

所以..如果我的父母組件創建像

<my-boundcomp [(ngModel)]="name" [(inputName)] ="name" ></my-boundcomp> 

子組件和我的子組件的OnInit功能是

public ngOnInit() { 
    console.log("Input Name :" + this.inputName); 
    console.log("Bound Name :" + this.boundName); 
    this._boundNameOnInit = this.boundName; // <--- Going to be null 
    this._inputNameOnInit = this.inputName; // <--- Going to be not null 

}

我發現這種行爲是奇數,並意外。我不確定這是一個錯誤還是我沒有正確使用FormsModule ngModel,但足夠有趣,我想我應該分享。

以下是完整的plnkr https://plnkr.co/edit/Im5oz7q1HhG5MgGTTZ1R?p=preview

回答

1

此代碼

[(ngModel)]="name" 

設置在OnInitBoundValueComponentNgModel值。 當從NgModel調用BoundValueComponent.writeValue時,則設置boundName

我很確定這是設計。

+0

如果是這樣的話,那麼我會訪問nginitode的oninit獲取值?這給了我相同的結果(https://plnkr.co/edit/POWoAgw8kYJToPhJwWQw?p=preview)。 –

+0

我不認爲你可以影響。你可以爲你的組件添加一個'@Input()ngModel;',但可能有其他不需要的副作用。 –

+1

我同意..我的觀點是,我仍然認爲這裏有些不太對勁。我不確定這是否按設計工作,爲什麼你不能訪問OnInit中的傳入值。 –

1

我相信這是一個「問題」,如果你是依賴於使用ControlValueAccessor當通過writeValue設置的值。由於boundName已設置,並且ngOnInit是第一件事情之一,writeValue還沒有機會運行。

我試着在一些其他生命週期掛鉤上添加這個(AfterViewInit,AfterContentInit),現在還爲時過早。事實上,如果你默認你boundName爲「」什麼的,你會發現,在AfterViewInitAfterContentInit,它實際上是在writeValue被調用之前清零了。

因此,我建議在writeValue方法中設置您的值。如果你只需要設置一次,你可以使用一個標誌。看到你的代碼如下...

export class BoundValueComponent implements OnInit, ControlValueAccessor { 

@Input() inputName: string; 
boundName: string; 

private _boundNameOnInit : string; 
private _inputNameOnInit : string; 

private initialized: boolean = false; 

private onTouchedCallback:() => void = noop; 
private onChangeCallback: (_: any) => void = noop; 

constructor() { 
} 

public ngOnInit() { 
    console.log("Input Name :" + this.inputName); 
    console.log("Bound Name :" + this.boundName); 
    // this._boundNameOnInit = this.boundName; // <--- Going to be null 
    this._inputNameOnInit = this.inputName; // <--- Going to be not null 
} 

get value(): any { 
    return this.boundName; 
}; 

/** 
* Set accessor including call the onchange callback. 
*/ 
set value(v: any) { 
    if (v !== this.boundName) { 
    this.boundName = v; 
    this.onChangeCallback(v); 
    } 
} 

/** 
* From ControlValueAccessor interface. 
*/ 
writeValue(value: any) { 
this.boundName = value; 

if (!this.initialized) { 
    this._boundNameOnInit = this.boundName; 
    this.initialized = true; 
} 
} 
....... 
相關問題