Angular 2中的OnInit中的ngModel绑定为null

时间:2016-10-03 16:03:34

标签: angular angular2-forms

我使用Angular 2 ngModel绑定遇到了一个问题。 plnkr

如果我使用ngModel将值绑定到子组件,则不会在子组件的OnInit函数上填充该值。所以如果我绑定一个属性调用" boundName"我尝试在OnInit中访问它,它将为null。但是,如果我将父控件中的相同值绑定到不使用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

2 个答案:

答案 0 :(得分:1)

此代码

[(ngModel)]="name"

设置NgModelOnInit的值不是BoundValueComponent。 从BoundValueComponent.writeValue调用NgModel后,即设置boundName

我很确定这是按照设计的。

答案 1 :(得分:1)

如果您在使用 ControlValueAccessor 时依赖于通过 writeValue 设置的值,我认为这是一个“问题”。由于设置了 boundName 并且 ngOnInit 是最先发起的事情之一,因此 writeValue 还没有机会运行。

我尝试在其他一些生命周期钩子上添加它( AfterViewInit,AfterContentInit ),现在还为时尚早。事实上,如果你将 boundName 默认为''或者你会注意到 AfterViewInit AfterContentInit ,它实际上是在< em> 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;
 }
}
.......