简体   繁体   English

将内容子项绑定到表单

[英]Bind content child to form

Is there a way to bind a projected template (ContentChild) to the form defined on the child ie add formControlName once rendered?有没有办法将投影模板 (ContentChild) 绑定到子项上定义的表单,即在呈现后添加formControlName

Struggling to know what to search for online as I may be using the wrong search terms.很难知道在网上搜索什么,因为我可能使用了错误的搜索词。

Non projected example - this works非投影示例 - 这有效

I have a form array (a particular example) below hooked up to a control value accessor,我在下面有一个表单数组(一个特定的例子)连接到一个控制值访问器,
The component has form group of type FormGroup<{ formArray: FormArray<{ formControl: FormControl }> }该组件具有FormGroup<{ formArray: FormArray<{ formControl: FormControl }> }类型的表单组
but on value changes I emit just the array of values ie formValue.formArray.map(v => v.formControl)但是在值变化时,我只发出值数组,即formValue.formArray.map(v => v.formControl)
So formArray and formControl are just holding names internally on the component.所以formArrayformControl只是在组件内部保存名称。

Particular example具体例子

<fieldset [formGroup]="formGroup">
    <legend>Paving runs (minimum 1)</legend>

    <ng-container formArrayName="formArray">
        <fieldset *ngFor="let frmGrp of formGroup.controls.formArray.controls; let i = index">
            <legend>Paving run</legend>
            
            <ng-container [formGroup]="frmGrp">
                <!-- what I want to project in a reusable version-->
                <paving-run-form
                    formControlName="formControl">
                </paving-run-form> 
            </ng-container>

            <button (click)="remove(i)">Delete run</button>
        </fieldset>
    </ng-container>
    
    <button (click)="add()">Add run</button>
</fieldset>

This is fairly standard and works but now I'm trying to create a reuseable component version of this.这是相当标准的并且可以工作,但现在我正在尝试创建一个可重用的组件版本。

So that I can do something like:这样我就可以做类似的事情:

<generic-form-array formControlName="paved_runs" [labels]="labels">
    <ng-template editMode>
        <paving-run-form></paving-run-form>
    </ng-template>
</generic-form-array>

where labels is in this case would be在这种情况下标签是

@Input() labels: GenericFormArrayOptions = {
    legendMany: "Paving runs (minimum 1)",
    legendOne: "Paving run",
    deleteOne: "Delete run",
    addOne: "Add run",
}

Projected example - what I've tried预计的例子 - 我试过的

<fieldset [formGroup]="formGroup">
    <legend>{{ labels.legendMany }}</legend>

    <ng-container formArrayName="formArray">
        <fieldset *ngFor="let frmGrp of formGroup.controls.formArray.controls; let i = index">
            <legend>{{ labels.legendOne }}</legend>
                
                    <ng-container [formGroup]="frmGrp">
                        <!-- project the form to edit one of array elements -->
                        <ng-container
                          [ngTemplateOutlet]="editModeTpl.templateRef">
                        </ng-container>
                    </ng-container>

            <button (click)="remove(i)">{{ labels.deleteOne }}</button>
        </fieldset>
    </ng-container>
    
    <button (click)="add()">{{ labels.addOne }}</button>
</fieldset>

With the following defined on the class:在 class 上定义了以下内容:

@ContentChild(EditModeDirective) editModeTpl!: EditModeDirective

ie uses the directive即使用指令

import { Directive, TemplateRef } from '@angular/core';

@Directive({
    selector: '[editMode]'
})
export class EditModeDirective {
    constructor(public templateRef: TemplateRef<any>) {}
}

In this case the content is projected as expected but <paving-run-form></paving-run-form> isn't bound to the child form.在这种情况下,内容按预期投影,但<paving-run-form></paving-run-form>未绑定到子表单。 Trying <paving-run-form formControlName="formControl"></paving-run-form> doesn't work because this is expecting formControl on the parent.尝试<paving-run-form formControlName="formControl"></paving-run-form>不起作用,因为这需要父级上的formControl

Is there some way to render the component and then add it to the child form?有什么方法可以渲染组件然后将其添加到子窗体吗?

Very typical that I solve just after asking the question...非常典型,我在问完问题后就解决了......

In the reuseable component I need to pass the form group via the context在可重用组件中,我需要通过上下文传递表单组

<ng-container
    [ngTemplateOutlet]="editModeTpl.templateRef"
    [ngTemplateOutletContext]="{formGroup: frmGrp}">
</ng-container>

and when using as a customer I need to do the following:作为客户使用时,我需要执行以下操作:

<generic-form-array formControlName="paved_runs">
    <ng-template editMode let-formGroup="formGroup">
        <paving-run-form [formControl]="formGroup.get('formControl')"></paving-run-form>
    </ng-template>
</generic-form-array>

Thanks to @Eliseo for leaving a helpful comment on a question I can no longer find:)感谢@Eliseo 对我再也找不到的问题留下了有用的评论:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM