2016-10-03 50 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; 
} 
} 
....... 
相关问题