带有表单组的 Angular ng-template

r3p*_*ica 10 reactive-forms angular

我希望创建一个有两个目的的组件,因为背后的代码是相同的。

所以我决定使用ng-template

第一部分是模态弹出窗口,html 如下所示:

<div class="modal fade" #modal="mdbModal" tabindex="-1" role="dialog" aria-labelledby="myBasicModalLabel"
    aria-hidden="true" mdbModal ng-if="!static && saveForm">
    <div class="modal-dialog">
        <div class="modal-content">
            <form class="card" [formGroup]="saveForm" (ngSubmit)="onSubmit()">
                <div class="modal-header">
                    <h4 class="modal-title pull-left">Are you sure?</h4>
                    <button type="button" class="close pull-right" aria-label="Close" (click)="modal.hide()">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <div *ngTemplateOutlet="form"></div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" (click)="modal.hide()">Cancel</button>
                    <button type="submit" class="btn btn-primary" (click)="modal.hide()">Save</button>
                </div>
            </form>
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

第二部分是静态形式,看起来像这样:

<form class="card" [formGroup]="saveForm" (ngSubmit)="onSubmit()" [ngClass]="{ 'mb-0': modal }"
    *ngIf="static && saveForm">
    <div class="card-header">
        <h3 class="card-title">{{editing ? 'Update': 'Create'}} your filter</h3>
    </div>
    <div class="card-body p-6">
        <div *ngTemplateOutlet="form"></div>
    </div>
    <div class="card-footer text-right">
        <div class="d-flex">
            <a routerLink="/feeds" class="btn btn-link" *ngIf="!modal">Back</a>
            <button type="submit" class="btn btn-primary ml-auto">Save</button>
        </div>
    </div>
</form>
Run Code Online (Sandbox Code Playgroud)

他们共享的模板如下所示:

<ng-template #form>
    <div class="form-group">
        <label class="form-label" for="name">Name</label>
        <input type="text" class="form-control" formControlName="name" placeholder="Enter the filter name"
            [ngClass]="{ 'is-invalid': submitted && f.name.errors }" />
        <div *ngIf="submitted && f.name.errors" class="invalid-feedback">
            <div *ngIf="f.name.errors.required">
                Name is required
            </div>
        </div>
    </div>
    <div class="form-group">
        <label class="form-label" for="name">Field name</label>
        <input type="text" class="form-control" formControlName="fieldName" placeholder="Enter the field name"
            [ngClass]="{ 'is-invalid': submitted && f.fieldName.errors }" />
        <div *ngIf="submitted && f.fieldName.errors" class="invalid-feedback">
            <div *ngIf="f.fieldName.errors.required">
                Field name is required
            </div>
        </div>
    </div>
    <div class="form-group">
        <label class="form-label" for="image">Operator</label>
        <select class="form-control" formControlName="filterOperator"
            [ngClass]="{ 'is-invalid': submitted && f.filterOperator.errors }">
            <option value="8">Between</option>
            <option value="2">Equal</option>
            <option value="4">Greater than</option>
            <option value="6">Less than</option>
            <option value="0">Like</option>
            <option value="9">Not between</option>
            <option value="3">Not equal</option>
            <option value="5">Not greater than</option>
            <option value="7">Not less than</option>
            <option value="1">Not like</option>
            <option value="10">Regular expression</option>
        </select>
        <div *ngIf="submitted && f.filterOperator.errors" class="invalid-feedback">
            <div *ngIf="f.filterOperator.errors.required">
                Operator is required
            </div>
        </div>
    </div>
    <div class="form-group">
        <label class="form-label" for="name">Expression</label>
        <input type="text" class="form-control" formControlName="expression" placeholder="Enter the expression"
            [ngClass]="{ 'is-invalid': submitted && f.expression.errors }" />
        <div *ngIf="submitted && f.expression.errors" class="invalid-feedback">
            <div *ngIf="f.expression.errors.required">
                Expression is required
            </div>
        </div>
    </div>
</ng-template>
Run Code Online (Sandbox Code Playgroud)

我希望这能正常工作,但我收到一条错误消息:

formControlName 必须与父 formGroup 指令一起使用。您需要添加一个 formGroup 指令并将其传递给现有的 FormGroup 实例(您可以在类中创建一个)。

这很烦人。有谁知道我该如何解决这个问题?

这是整个html:

<div class="modal fade" #modal="mdbModal" tabindex="-1" role="dialog" aria-labelledby="myBasicModalLabel"
    aria-hidden="true" mdbModal ng-if="!static && saveForm">
    <div class="modal-dialog">
        <div class="modal-content">
            <form class="card" [formGroup]="saveForm" (ngSubmit)="onSubmit()">
                <div class="modal-header">
                    <h4 class="modal-title pull-left">Are you sure?</h4>
                    <button type="button" class="close pull-right" aria-label="Close" (click)="modal.hide()">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <div *ngTemplateOutlet="form"></div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" (click)="modal.hide()">Cancel</button>
                    <button type="submit" class="btn btn-primary" (click)="modal.hide()">Save</button>
                </div>
            </form>
        </div>
    </div>
</div>

<form class="card" [formGroup]="saveForm" (ngSubmit)="onSubmit()" [ngClass]="{ 'mb-0': modal }"
    *ngIf="static && saveForm">
    <div class="card-header">
        <h3 class="card-title">{{editing ? 'Update': 'Create'}} your filter</h3>
    </div>
    <div class="card-body p-6">
        <div *ngTemplateOutlet="form"></div>
    </div>
    <div class="card-footer text-right">
        <div class="d-flex">
            <a routerLink="/feeds" class="btn btn-link" *ngIf="!modal">Back</a>
            <button type="submit" class="btn btn-primary ml-auto">Save</button>
        </div>
    </div>
</form>

<ng-template #form>
    <div class="form-group">
        <label class="form-label" for="name">Name</label>
        <input type="text" class="form-control" formControlName="name" placeholder="Enter the filter name"
            [ngClass]="{ 'is-invalid': submitted && f.name.errors }" />
        <div *ngIf="submitted && f.name.errors" class="invalid-feedback">
            <div *ngIf="f.name.errors.required">
                Name is required
            </div>
        </div>
    </div>
    <div class="form-group">
        <label class="form-label" for="name">Field name</label>
        <input type="text" class="form-control" formControlName="fieldName" placeholder="Enter the field name"
            [ngClass]="{ 'is-invalid': submitted && f.fieldName.errors }" />
        <div *ngIf="submitted && f.fieldName.errors" class="invalid-feedback">
            <div *ngIf="f.fieldName.errors.required">
                Field name is required
            </div>
        </div>
    </div>
    <div class="form-group">
        <label class="form-label" for="image">Operator</label>
        <select class="form-control" formControlName="filterOperator"
            [ngClass]="{ 'is-invalid': submitted && f.filterOperator.errors }">
            <option value="8">Between</option>
            <option value="2">Equal</option>
            <option value="4">Greater than</option>
            <option value="6">Less than</option>
            <option value="0">Like</option>
            <option value="9">Not between</option>
            <option value="3">Not equal</option>
            <option value="5">Not greater than</option>
            <option value="7">Not less than</option>
            <option value="1">Not like</option>
            <option value="10">Regular expression</option>
        </select>
        <div *ngIf="submitted && f.filterOperator.errors" class="invalid-feedback">
            <div *ngIf="f.filterOperator.errors.required">
                Operator is required
            </div>
        </div>
    </div>
    <div class="form-group">
        <label class="form-label" for="name">Expression</label>
        <input type="text" class="form-control" formControlName="expression" placeholder="Enter the expression"
            [ngClass]="{ 'is-invalid': submitted && f.expression.errors }" />
        <div *ngIf="submitted && f.expression.errors" class="invalid-feedback">
            <div *ngIf="f.expression.errors.required">
                Expression is required
            </div>
        </div>
    </div>
</ng-template>
Run Code Online (Sandbox Code Playgroud)

tan*_*ano 22

您应该将 传递formGroup给模板:

<ng-template #form let-form="form">
  <div [formGroup]="form">
  ...
  </div>
</ng-template>
Run Code Online (Sandbox Code Playgroud)

然后这样称呼它:

<ng-container *ngTemplateOutlet="form; context: {form: saveForm}"></ng-container>
Run Code Online (Sandbox Code Playgroud)