2017-11-25 143 views
1

使用Angular 4.x我创建了动态表单。 (它允许根据情况添加或删除字段。) 一开始就一切都很好。所有值(开始,结束,类别)都有一个在模板中设置的初始值。在视觉上,一切看起来都很完美如果根据页面上的其他对象或与页面上的其他对象同步正确猜测值,则用户无需更改任何内容。角4动态表单 - 如果未触及空值 - 如何获得这些显示的默认值?

问题:如果用户没有更改这些值,它们将从窗体返回为“”。尽管在页面上展示了不错的内容。 已经玩过很多原始/肮脏和感动的旗帜。没有改变。

最后,我找到了开始和结束值的解决方法。不是很漂亮。只需在typescript中进行相同的日期转换,并将formbuilder中的开始和结束值设置为完全相同的东西。以为我可以从模板中删除value =来减少重复的代码。但是,如果我这样做,输入字段在页面上保持空白。

但是,此解决方法无法用于category_id事件,该事件可以在页面上实时更改。更好的是,categoriesService.selectedCategory可以是none。我们会对categoriesService.selectedCategory.id字段感兴趣。

页面上的视觉事物完成,看起来不错。但是如何在提交时从页面获取这些值? (即使用户没有与价值观玩)

这是我的模板看起来像:

<form [formGroup]="myNewCustForm" novalidate (ngSubmit)="save(myNewCustForm)"> 
... 
<label>product</label> 
<select class="form-control" formControlName="category_id"> 
    <option 
    *ngFor="let category of categoriesService.categories" 
    [ngValue]="category.id" 
    [selected]="categoriesService.selectedCategory ? category.id === categoriesService.selectedCategory.id : false"> 
     {{category.name}} 
    </option> 
</select> 
... 
<label>start</label> 
<div class="input-group"> 
    <input 
    class="form-control" 
    placeholder="yyyy-mm-dd" 
    name="dprestart" 
    ngbDatepicker 
    #dpstart="ngbDatepicker" 
    value="{{startDate | date: 'yyyy-MM-dd'}}" 
    formControlName="start"/> 
    <button 
    class="input-group-addon" 
    (click)="dpstart.toggle()" 
    type="button"> 
    <i class="fa fa-calendar" aria-hidden="true"></i> 
    </button> 
</div> 

打字稿(角4.x版):

return this.formBuilder.group({ 
    start: this.startDateString, 
    end: this.endDateString, 
    category_id: '' 
}); 

而在保存方法:有关的startDate和结束日期

this.presences.value.forEach(presence => { 
    ... 
    console.log(presence.start); 
    console.log(presence.category_id); 
    ... 
} 

更多信息:

// presence default values - declarations 
startDate: Date; 
startDateString: string; 
endDate: Date; 
endDateString: string; 

,然后在呼吁ngInit方法:

this.endDate = new Date(Date.now()); 
this.endDate.setHours(0, 0, 0); 
if(this.endDate.getDay() > 4) { 
    this.endDate.setDate(this.endDate.getDate()+13-(this.endDate.getDay() || 7)); 
} else { 
    this.endDate.setDate(this.endDate.getDate()+6-(this.endDate.getDay() || 7)); 
} 
this.startDate = new Date(Date.now()); 
this.startDateString = this.datePipe.transform(this.startDate, 'yyyy-MM-dd'); 
this.endDateString = this.datePipe.transform(this.endDate, 'yyyy-MM-dd'); 
+0

刚刚发现了另一个解决方法。现在只要检查结果是否返回“”。如果是这样,我会尝试重新计算默认值可能是什么。有没有干净的方式? – user3387542

+0

此替代方法也不起作用。 – user3387542

+0

这是否有一个笨蛋? –

回答

1

与活性形式,像valuedisabledselected不起作用。你需要做的是利用表单控件,并做他们想做的事情。此外,与ngbDatepicker,它想要的价值,应该是NgbDateStruct类型,看起来像:

{ 
    "year": 2017, 
    "month": 11, 
    "day": 22 
} 
与日期选取器

所以,你需要的日期格式,以便日期选择接受它,这里有一个如何一个简单的示例它应该看起来像:

startDateString: NgbDateStruct = {year: new Date().getFullYear(), 
            month: new Date().getMonth() + 1, 
            day: new Date().getDate()}; 

然后,您将分配给表单控件,就像你有。

对于select,如上所述,Angular完全不关心selected。什么,你需要做的是与你的服务越来越每当它改变了值使用patchValue(或setValue):

this.myNewCustForm.controls.category_id.setValue('some value') 

看来你是使用服务此值。然后可以使用settergetter来达到此目的将值设置为表单控件。