【问题标题】:Angular 8: Using a single form with multiple sibling componentsAngular 8:使用具有多个兄弟组件的单个表单
【发布时间】:2019-10-01 05:27:19
【问题描述】:

有没有一种方法可以让我使用反应式表单来使用一个表单并将其用于我的所有其他组件?

我正在制作一个基本的 CRUD 应用程序,它运行良好。问题是每个组件都有自己的模板,但我想使用相同的表单来创建客户信息,使用引导模式中显示的相同表单更新客户信息。

我是新手,无法解决问题。

我创建了一个响应式表单组件,其中包含响应式表单的 html。但我不知道如何在每个组件中重用它们。

【问题讨论】:

  • 是的,当您想要更新项目时,您可能只需要将数据注入form.component.ts,因为您需要IDsorting-list-angular.web.app。我会写在answear代码中。
  • 很棒的应用程序!我想要一个完全相同的东西。有没有我可以遵循的教程?
  • 在回答中,您在 bitbucket 上拥有整个应用程序代码的所有内容
  • 关于教程是的,你可以在互联网上找到一些,但在这个例子中,我正在研究 NGXS 库,所以我不记得有任何指向 CRUD 教程的链接。

标签: angular angular-reactive-forms angular8


【解决方案1】:

是的,您可以向[formGroup]="form" 添加任何元素,它将成为该表单的一部分。它也适用于子组。你应该输入@Input() form: FormGroup

与输入字段位于同一组件中的任何父 HTML 元素都可以输入 formGroup

【讨论】:

  • 我可以对所有组件使用相同的 html,我的意思是问?我不明白你在最后一行的意思
  • 对不起,说的不够清楚,我已经重写了第二句。
  • 谢谢你我明白你的意思了:) 我的另一个问题是是否可以使用相同的表单组(和模板)作为另一个组件的模板?比如说,我想使用相同的表单来创建和更新客户信息。那可能吗?我想减少样板代码,而不是重复基本服务于相同目的的相同表单组。
  • 是的,当然。您有专门的组件,它只处理表单逻辑并在提交时输出结果。您还可以在父组件中创建表单组对象并将其传递给该子组件。唯一的限制是带有 formControlName 的输入字段必须是 FormGroup 对象中的字段(FormGroup 字段不需要 DOM 表示)。如果你不想要它,用 ngIf 隐藏它。
【解决方案2】:

带有排序列表的示例 CRUD:https://sorting-list-angular.web.app/library 整个应用的Git:https://bitbucket.org/mises543/sorting-list/src/master/

这是一个简单的应用程序,其中的 NGXS 有点矫枉过正,但我​​正在学习。它是数据状态管理。它被称为 Redux。

你可以学习一下。

模板:

<div class="add-item-container">
  <mat-label>
    <h2>Add Media</h2>
  </mat-label>
  <section>
    <mat-form-field>
      <input matInput placeholder="Enter title:" type="text" [formControl]='title' required>
      <mat-error *ngIf="title.invalid && !''">{{getErrorTitle()}}</mat-error>
    </mat-form-field>
    <mat-form-field>
      <mat-select matInput placeholder="Category:" [formControl]="category" required>
        <ng-container *ngFor="let category of categories">
          <mat-option *ngIf="category != 'All'" [value]="category">{{category}}</mat-option>
        </ng-container>
      </mat-select>
      <mat-error *ngIf="category.invalid && !''">{{getErrorCategory()}}</mat-error>
    </mat-form-field>
    <mat-form-field>
      <input matInput [matDatepicker]="picker1" placeholder="Upload Date:" [formControl]="uploaded">
      <mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
      <mat-datepicker #picker1></mat-datepicker>
    </mat-form-field>
    <div class="buttons">
      <ng-container *ngIf="data; then update; else add"></ng-container>
      <ng-template #add>
        <button mat-raised-button color="primary" (click)="onAdd()" [disabled]="title.invalid || category.invalid">Add
          item</button>
      </ng-template>
      <ng-template #update>
        <button mat-raised-button color="primary" (click)="onUpdate()"
          [disabled]="title.invalid || category.invalid">Update
          item</button>
      </ng-template>


      <button mat-raised-button color="primary" (click)="onCancel()">Cancel</button>
    </div>
  </section>
</div>

模板中最重要的是按钮,因此当父组件有输入数据时显示按钮更新或没有任何数据时添加按钮:

<ng-container *ngIf="data; then update; else add"></ng-container>
      <ng-template #add>
        <button mat-raised-button color="primary" (click)="onAdd()" [disabled]="title.invalid || category.invalid">Add
          item</button>
      </ng-template>
      <ng-template #update>
        <button mat-raised-button color="primary" (click)="onUpdate()"
          [disabled]="title.invalid || category.invalid">Update
          item</button>
      </ng-template>

form.component.ts 使用@angular/material 库以防弹出对话框:

categories = MediaOptions.CATEGORIES

  uploaded = new FormControl(new Date(), [Validators.required])
  title = new FormControl('', [Validators.minLength(5), Validators.required])
  category = new FormControl('', [Validators.required])

  constructor(private store: Store,
    private snackBar: SnackService,
    public dialogRef: MatDialogRef<AddItemComponent>,
    @Inject(MAT_DIALOG_DATA) public data?: any) {}

  ngOnInit(): void {
    if(this.data) {
      this.title.setValue(this.data.title)
      this.category.setValue(this.data.category)
      this.uploaded.setValue(this.data.uploaded)
    } else {
      this.uploaded.setValue(new Date())
    }
  }

带有功能打开对话框的父组件:

constructor(private store: Store, private snackBar: SnackService, private dialog: MatDialog) { }

  async ngOnInit() {
    this.store.dispatch(new GetMedia())
  }

  editItem(payload: any) {
    this.dialog.open(AddItemComponent,
      { width: '500px', data: payload });
  }

  addItem() {
    this.dialog.open(AddItemComponent,
      { width: '500px' });
  }

【讨论】:

    猜你喜欢
    • 2017-04-01
    • 2019-11-22
    • 2019-06-12
    • 2020-02-16
    • 2015-05-17
    • 1970-01-01
    • 2020-11-22
    • 2016-06-23
    • 2017-10-21
    相关资源
    最近更新 更多