【问题标题】:Reactive Form consisting of multiple components由多个组件组成的反应式表单
【发布时间】:2020-01-07 05:25:21
【问题描述】:

似乎没有这方面的任何信息,所以我想我会在这里问:

我正在创建一个有角度的表单,其中每个输入字段后面都有单选按钮,这些单选按钮仅在用户对相应的输入字段进行任何更改后才会出现。 我的单选单输入字段模板如下所示:

<div class="form-group row">
    <label class="col-sm-3 col-form-label">
        <strong>My Title One</strong>
    </label>
    <div class="col-sm-9">
        <input type="text" class="form-control" id="titleone"
            formControlName="titleone" #titleone placeholder="no input yet" (input)="titleoneChanged = true">
        <div *ngIf="titleoneChanged">
            <label>
                <input type="radio" name="titleoneConfirm" value="Val 1" formControlName="titleoneConfirm">
                Option 1
            </label>
            <label>
                <input type="radio" name="titleoneConfirm" value="Val 2" formControlName="titleoneConfirm">
                Option 2
            </label>
            <label>
                <input type="radio" name="titleoneConfirm" value="Val 3" formControlName="titleoneConfirm">
                Option 3
            </label>
        </div>
    </div>
</div>

这个块在我的表单中重复了大约 20 次。

表单 TS 看起来像这样:

export class GiantForm implements OnInit {
    form: FormGroup;
    //some more variables, which i can not show

    initForm(){
        if(this.someApiSource === null || this.someApiSource === undefined){
            return;
        }
        this.form = this.formBuilder.group({
            Subform1:this.formBuilder.group({
                firstName:[this.someApiSource.getFirstName()],
                lastName:[this.someApiSource.getLastName()],
            }),
            //some more subforms...
            subFormWithInputAndRadios:this.formBuilder.group({
                titleone:[this.someApiSource.getInfo('titleone')],
                titletwo:[this.someApiSource.getInfo('titletwo')],
                titlethree:[this.someApiSource.getInfo('titlethree')],
                titlefour:[this.someApiSource.getInfo('titlefour')],
                //20 titles...

                titleoneConfrim:[this.someApiSource.getInfo('titleoneConfirm')],
                titletwoConfrim:[this.someApiSource.getInfo('titletwoConfirm')],
                titlethreeConfrim:[this.someApiSource.getInfo('titlethreeConfirm')],
                //20 title confirms...
            })
            }
        );
    }
}

我不太喜欢这种方法。在我看来它一点也不干净。

如果有人对此有更好的解决方案,请告诉我。现在我需要知道,如何将模板更改为这样的:

<div class="form-group row">
    <label class="col-sm-3 col-form-label">
        <strong>My Title One</strong>
    </label>
    <div class="col-sm-9">
        <input type="text" class="form-control" id="titleone"
            formControlName="titleone" #titleone placeholder="no input yet" (input)="titleoneChanged = true">
        <app-radiobutton-component></app-radiobutton-component>
    </div>
</div>

并且让新组件中的输入仍然适用于正确的表单控件。

我尝试使用@Input 传递表单控件,但它总是导致某种错误。例如:

        <div>
            <label>
                <input type="radio" name="inputName" value="Val 1" formControlName="inputControl">
                Option 1
            </label>
            <label>
                <input type="radio" name="inputName" value="Val 2" formControlName="inputControl">
                Option 2
            </label>
            <label>
                <input type="radio" name="inputName" value="Val 3" formControlName="inputControl">
                Option 3
            </label>
        </div>

radiobutton.component.html 内

在 radiobutton.component.ts 中

export class RadioButtonComponent implements OnInit{
    @Input() inputName: string;
    @Input() inputControl: FormControl;
    //...
}

导致一些错误,例如找不到表单控件

感谢我能得到的任何帮助。如果有人知道整个表单的更好的整体解决方案,而不仅仅是模板部分,请告诉我

【问题讨论】:

    标签: javascript html angular typescript


    【解决方案1】:

    所以我做了一些进一步的实验,结果证明您可以将表单控件作为字符串传递给您的子组件。并且主表单组也需要传递:

    在父组件中

    <div class="form-group row">
        <label class="col-sm-3 col-form-label">
            <strong>My Title One</strong>
        </label>
        <div class="col-sm-9">
            <input type="text" class="form-control" id="titleone"
                formControlName="titleone" #titleone placeholder="no input yet" (input)="titleoneChanged = true">
            <app-radiobutton-component [inputName]="'titleoneConfirm'" [inputControl]="'titleoneConfirm'" [form]="'form'"></app-radiobutton-component>
        </div>
    </div>
    

    在子组件中:

    export class RadioButtonComponent implements OnInit{
        @Input() inputName: string;
        @Input() inputControl: string;
        @Input() form: string;
        //...
    }
    
            <div [formGroup]="{{form}}">
                <label>
                    <input type="radio" name="{{inputName}}" value="Val 1" formControlName="{{inputControl}}">
                    Option 1
                </label>
                <label>
                    <input type="radio" name="{{inputName}}" value="Val 2" formControlName="{{inputControl}}">
                    Option 2
                </label>
                <label>
                    <input type="radio" name="{{inputName}}" value="Val 3" formControlName="{{inputControl}}">
                    Option 3
                </label>
            </div>
    

    这在我的情况下很完美。不知道这是否是真正的角度方式,但它有效

    【讨论】:

      【解决方案2】:
      1. 对于第一部分:使用 FormArray。 https://angular.io/api/forms/FormArray。您还可以找到很多关于此的优秀教程
      2. 对于 RadioButtonComponent 部分。要在 Angular 中自定义表单组件,您需要实现 ControlValueAccessor。看看这个https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html#understanding-controlvalueaccessor

      【讨论】:

        猜你喜欢
        • 2016-04-27
        • 2021-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-12
        • 1970-01-01
        • 2019-09-18
        • 2022-11-10
        相关资源
        最近更新 更多