我有一个嵌套的反应形式,我想将其拆分为几个部分。
我定义了基本表单,但是我想避免为父级子组件定义表单模型,因为我认为它们不属于这里。
buildChamberForm() {
return this.formBuilder.group({
_id: [''],
__v: [''],
name: [ '', Validators.required ],
cycle: [ '', Validators.required ],
strains: this.formBuilder.array([])
rules: this.formBuilder.array([])
})
}
buildChambersForm() {
return this.formBuilder.group({
chambers: this.formBuilder.array( [] )
})
}
<app-setting-strains [chamberStrains]="chamber.strains" [chamberCycle]="chamber.cycle"></app-setting-strains>
<app-setting-lights [chamberRules]="chamber.rules" [chamberCycle]="chamber.cycle"></app-setting-lights>
<app-setting-fans [chamberRules]="chamber.rules"></app-setting-fans>
分庭规则分为不同的子部分,例如粉丝规则。
<app-input-rule [chamberRules]="chamberRules" [ruleDevice]="'fan'" placeholder="'e.g. Air circulation (Left)'"></app-input-rule>
在(某些)子组件中,使用输入规则格式。其他子组件使用其他输入组件。
createRuleForm(device?, trigger?) {
const ruleForm = this.formBuilder.group({
_id: [''],
sensor: [''],
device: [device || ''],
forDetector: [''],
detectorId: [''],
trigger: [trigger || ''],
startTime: [''],
durationHOn: [''],
durationOn: [''], // TODO: this is temporary
timeUnit: [''], // TODO: this is temporary
durationMSOn: [''],
onValue: [''],
offValue: [''],
onPattern: [''],
durationMBlocked: [''],
nightOff: [''],
relay: ['']
})
return ruleForm
}
createRulesForms() {
const rulesForm = this.formBuilder.group({
rules: this.formBuilder.array( [] ) // TODO: validator depending on rule type
})
// console.log("rulesForm", rulesForm)
return rulesForm
}
这是在输入规则组件中使用组件的示例。输入规则组件中有多个输入。
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-8">
<app-input-relay *ngIf="rule.get('relay')" [label]="capitalizeFirstletter(ruleDevice) + 'Relay'" [class]="'tutorial-step'" [relay]="rule.get('relay')" [placeholder]="placeholder"></app-input-relay>
</div>
</div>
输入继电器是设置规则参数的几个组件之一。
<div class="form-group col-xs-6 col-sm-6" *ngIf="relay.value">
<label>Rename Relay</label>
<input type="text" class="form-control" [ngClass]="class" [formControl]="name" [placeholder]="placeholder" (keyup)="debouncedRename(this.relay.value, this.name.value)"/>
</div>
将子表单保留在子组件中,而不是在父组件中定义整个表单。或者,如果这是将所有内容都移到表单构建器服务中的正确方法,那么
在我当前的设置中,我无法使用setValue来初始化高级组件中的表单,因为高级组件不了解例如中的子表单。 FormArray
strains
因此出错:
There are no form controls registered with this array yet.
我可以使用patchValue
解决此问题,但我认为这是反模式的。
是否最好在parent.component中定义表单,还是应该将所有内容移到具有所有表单构建方法的服务中?
1.1如果我将其留在父母中,该怎么做?
1.2如果我将其移至服务,则该服务应该是有状态的并包含表单值,还是最好像在上面的html示例中那样使用输入在服务中窥视该表单并将其传递下来?
1.2.1我也需要输出吗?我读到某个地方,反应形式以某种方式处理了这个问题。
那些有用的问题,但基本上都只是一个问题,什么是将复杂的嵌套形式分为几个部分的正确方法。
在带有服务的示例中:
https://blog.grossman.io/real-world-angular-reactive-forms/
但是大多数示例都将表单逻辑放入组件中(但是它们也没有显示如何在组件之间进行拆分):
这个使用输入/输出:
(但我读到某处不应该使用反应式表单)
答案 0 :(得分:0)
我遇到了相同的问题,但模板驱动表单。在所有子组件中,我声明:
@Component({
...
viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],
})
由于这一点,我为将表单拆分为子组件的单个NgForm
句柄。我不确定这个概念是否适用于反应形式。
答案 1 :(得分:0)
您可以在父组件中维护一个FormGroup,它将通过@input传递给子组件。在子组件内部,可以使用addControls()添加任何输入控件。
可以使用formGroup.value在父组件中访问这些子组件值。