【问题标题】:ng-content rendered custom form controlsng-content 呈现自定义表单控件
【发布时间】:2025-11-21 08:15:02
【问题描述】:

我正在开发一个多页表单(有点像向导),其中包含一个或多个控件页面,这些控件将是自定义控件。

这是我正在尝试开发的图片:

这是(到目前为止)一个模板驱动的表单,下面是它背后的模板:

<multiform [debug]="true" [title]="'New Job'">
    <multiform-page [title]="'Basics'" >Page for job basics
        <trk-select
            [placeholder]="'Research Client'"
            [fieldId]="fields.client.key"
            [options]="toTrkOptions(fields.client)"
            [multiple]="true">
        </trk-select>
    </multiform-page>
    <multiform-page [title]="'Detail 1'" >This is the first detail page</multiform-page>
    <multiform-page [title]="'Detail 2'" >More details go here</multiform-page>
</multiform>

我原本打算在&lt;multiform&gt; 中包含&lt;form&gt;

multiform.control.html

{{title}}
<div class="tabset">
    <a *ngFor="let page of pages"
       [class.tab]="true"
       [class.hidden-tab]="false"
       [class.active]="page.active"
       (click)="activatePage(page)">
        {{page.title}}
    </a>
</div>
<form #form="ngForm">
    <ng-content></ng-content>
</form>

<div *ngIf="debug">
    <h1>Form Values</h1>
    <pre>{{form.value | json}}</pre>
</div>

在每个&lt;multiform-page&gt; 中都有许多自定义表单控件。在此示例中,只有一个 &lt;trk-select&gt; 控件,但它会增长。

单独的表单控件被投影,如下所示:

multiform-page.component.html

<div class="content" [class.active]="active">
    <ng-content></ng-content>
</div>

我的选择控件工作正常。当我将它直接包含在表单中(不使用)时,它也可以正常工作。它也被投射到我的&lt;multiform&gt; 上。现在是时候把它变成一个真实的形式了,那时一切都崩溃了。

我希望multiform 拥有实际的&lt;form&gt; 组件,并将控件绑定到它。

但我不能这样做:

<div class="content" [class.active]="active">
    <ng-content [(ngModel)]="field"></ng-content>
</div>

因为我不知道field 在这里是什么。 (记住,会有多个控件,它们不能都绑定到同一个变量)

所以这里的架构看起来像这样:

<multiform>
  |--> has <form>
  |--> projects <multiform-page>
                     |
                     |--> projects custom control 1
                     |--> projects custom control 2

但我不知道如何将这些控件绑定到表单。我该怎么做?

【问题讨论】:

    标签: angular angular2-forms transclusion


    【解决方案1】:

    你应该使用选择器

    <div class="content" [class.active]="active">
        <ng-content select=".multiform-body"></ng-content>
    </div>
    

    你必须将你的 html 推送为

    <div>
       <div class="multiform-body>
          ...........................................
          these contents are replaced in your multiform component
        </div>
    </div>
    

    更新:

    <multiform [debug]="true" [title]="'New Job'">
        <multiform-page [title]="'Basics'" >Page for job basics
        <div class="multiform-body">
            <basics-component> </basics-component>
        </div>
    
    
        </multiform-page>
        <multiform-page [title]="'Detail 1'" >
        <div class="multiform-body">
            <detail1-component> </detail1-component>
            This is the first detail page
        </div>
        </multiform-page>
        <multiform-page [title]="'Detail 2'" >
    
        <div class="multiform-body">
            <detail2-component> </detail12-component>
            This is the first detail page
        </div>
    
        </multiform-page>
    </multiform>
    

    更新 2:

    当您使用将在整个应用程序中使用的自定义控件时,您可以将它们组合为 CustomControls,并将它们分别作为单独的组件。

    例如,您的应用程序中有以下组件

    1. 学生下拉菜单
    2. 教师下拉菜单

    所以你应该有一个单独的&lt;students-dropdown&gt;&lt;teachers-dropdown&gt; 使用一些输入和输出变量来操作数据。

    根据评论更新绑定选中值&lt;trk-select&gt;,关注这些

    <trk-select (change)="trkChanged($event)"><trk-select>
    
    <detail-component (trkChange)="trkChanged($event)"> </detail-component>
    
    <multi-form>
       <detail-component (trkChange)="trkChanged($event)"> </detail-component>
    </multi-form>
    

    所以三个发射变量在各自的组件中。

    【讨论】:

    • 我正在努力理解您在这里所说的内容。当您说“将您的 html 推送为...”时,您指的是哪个 html?那是页面上的控件吗? IOW 你是说我需要将我的&lt;trk-select&gt; 组件包装在div 中吗?抱歉,我有点糊涂了。
    • 刚刚看到您正在编辑,这更有意义,谢谢。仍然不太明白如何让&lt;detail1-component&gt; 上的控件绑定到&lt;multiform&gt; 上的表单。你能帮我理解吗?
    • 我没听懂你的问题,你能详细说明一下吗?
    • 当然。 &lt;detail-component&gt; 上面会有一个&lt;trk-select&gt;。那是一个自定义表单控件。我想将&lt;trk-select&gt; 组件中所做的选择绑定到&lt;multiform&gt; 上的&lt;form&gt; 组件。
    • 所以我有(A)&lt;multiform&gt;,上面有一个&lt;form&gt;,并投射了多个(B)&lt;multiform-page&gt;。每个&lt;miltiform-page&gt; 项目 (C) 多个自定义表单控件(如输入、选择等)。如何获取 (C) 中的更新以绑定到 (A) 中的表单?