Angular 设置ng引导字段的默认值(ngModels不能使用getter/setter)

Angular 设置ng引导字段的默认值(ngModels不能使用getter/setter),angular,angular2-forms,ng-bootstrap,Angular,Angular2 Forms,Ng Bootstrap,我在一个表单中使用了一个字段,我想用一个默认值初始化它 在“标准”形式中,我可以使用formControlName或ngModel,它可以正常工作: 我的问题是,我将日期选择器包装在自己的自定义字段中,即实现ControlValueAccessor的自定义组件 在此场景中,日期选择器不再知道其父窗体和相应的模型。那么如何初始化datepicker字段呢 formControlName不是选项(我的自定义字段组件没有也不应该访问其父窗体的模型) ngModel似乎更简单,因为它只是一个本地属

我在一个表单中使用了一个字段,我想用一个默认值初始化它

在“标准”形式中,我可以使用
formControlName
ngModel
,它可以正常工作:


我的问题是,我将日期选择器包装在自己的自定义字段中,即实现
ControlValueAccessor
的自定义组件

在此场景中,日期选择器不再知道其父窗体和相应的模型。那么如何初始化datepicker字段呢

  • formControlName
    不是选项(我的自定义字段组件没有也不应该访问其父窗体的模型)
  • ngModel
    似乎更简单,因为它只是一个本地属性的绑定,但只要我将
    [(ngModel)]
    指令添加到datepicker字段,我的整个表单就会冻结
以下是迄今为止我的自定义字段组件的代码:

@组件({
选择器:“字段日期时间”,
模板:`
`,
供应商:[
{provide:NG_VALUE_访问器,useExisting:forwardRef(()=>FieldDateTimeComponent),multi:true}
]
})
导出类FieldDateTimeComponent实现ControlValueAccessor{
private _dateTimeObj:DateTime;//日期在内部存储为对象
传播变化=((uu0:any)=>{};
//将新值写入元素(从表单模型写入视图)。
writeValue(时间戳:数字){
//解析时间戳以在内部将其存储为对象。
这是._dateTimeObj=时刻(timestamp).toObject();
此.propagateChange(此._dateTimeObj);
}
注册变更(fn:任何){
这一变化=fn;
}
(fn:any){}
//这是我要绑定到字段的属性,即:
// 
//这是错误的。不要对NGMODEL使用GETTER。请参阅下面的答案。
获取dateObj(){
返回{day:this.\u dateTimeObj.date,month:this.\u dateTimeObj.months,year:this.\u dateTimeObj.years};
}
}

正确的解决方案显然是使用
[(ngModel)]
。你真正的问题是,当你尝试使用它时,它会冻结

我认为问题在于在writeValue中调用propagateChanges,这会触发无限循环。 请尝试以下操作:

html:


啊。。。问题在于ngModel使用了getter/setter(与ng引导无关)

换句话说,给定模板中的此字段:


foo
属性不能在类中使用getter/setter:

导出类MyComp(){
私人(乌富);
getfoo(){
把这个还给我;
}
设置foo(val){
这个。_foo=val;
}
}
但为了仍然能够对模型更改做出反应(这是首先使用getter/setter的全部目的),我必须重写
ngModel
指令以使用其扩展形式:


现在,
onFooChanged()
允许我将更改
从自定义字段传播到父表单(就像setter允许我那样)


(在我最初的示例中,
get dateObj()
就是问题所在。用标准类属性替换它+使用上面的语法修复它。)

[(ngModel)]是正确的解决方案。你能添加一些代码吗?作为一个粗略的猜测,我可以在ControlValueAccessor实现中的某个地方想到一个无限循环,比如writeValue调用setter,setter调用writeValue,或者类似的东西。@VincentV。谢谢你抽出时间。我已经用一些代码更新了这个问题。原来问题是ngModel使用了getter。我用一个标准类属性替换了它,它可以正常工作。不过,谢谢你给我指出了正确的方向。如果没有你的评论,我会放弃ngModel。你几乎可以用一个向上投票来表达你的感激之情,那么:p
<input class="form-control" ngbDatepicker #d="ngbDatepicker" (change)="handleChange()" [(ngModel)]="_dateTimeObj">
writeValue(timestamp: number) {
  // Parse the timestamp to store it as an object internally.
  this._dateTimeObj = moment(timestamp).toObject();
}
handleChange($event) { 
  // manage sending the value back from the input to your model using $event.target.value
  this.propagateChange(this._dateTimeObj);
}