【问题标题】:Complex Angular forms with dynamically changing sub-forms具有动态变化的子表单的复杂 Angular 表单
【发布时间】:2018-03-26 07:34:29
【问题描述】:

这是来自 Google 日历的屏幕截图。如何在 Angular/Material(目前分别为 4.4.4 和 2.0.0-beta.12)中构建这个接口?

注意:我发现 Angular 和 Material 有两个特别具有挑战性的功能。

  1. 整个表单会根据第一个选择框而变化。 “每天重复”计算天数,而“每周重复”提供一周中特定日期的复选框。 (“每月重复一次”也提供了独特的选项。)我真的更喜欢模块化解决方案,在那里我可以将互斥的子表单分解为它们自己的组件/表单组。在存在 ngIf 的情况下管理验证也让我很头疼。

  2. “结束:”块是一个组合单选按钮,带有用于某些选项的数字和日期输入。我不确定如何用 angular+material 来近似,或者如何设置验证。我也很乐意将“Ends”设置为一个选择框,但在这种情况下,我不希望后面的 0 或 1 输入字段有单独的组件/表单组。所以我不能完全把它简化为问题#1的一个实例。

【问题讨论】:

标签: angular angular2-forms angular-material2


【解决方案1】:

我必须为应用构建相同的组件,虽然它基于 OSX 提醒调度程序,但大致相同。

最好只关注“结束”选择,因为可以在整个组件中应用相同的概念。 endFormGroup 是更大的 FormGroup 中的一个控件,它看起来像这样

end: this.fb.group({
  // default to 'never'. Can also be 'date' or 'count'
  selection: 'never',
  // default the date to one week from now
  date: [startOfDay(addDays(oneHourFromNow, 7)), Validators.required],
  // default to only repeating once
  count: [1, [Validators.required, CustomValidators.number(this.countLimits)]]
})

显然,如果您只是按原样提交此表单,它将包含一个没有多大意义的值。为了解决这个问题,您需要根据需要使用enabledisable datecount 控件。当抽象控件被禁用时,它不会包含在表单值中。

this.endGroup.get('selection').valueChanges
  .startWith(null)
  .subscribe(() => {
    // if the selection value is 'never',
    // disable both the 'date' and 'count' controls

    // if the selection value is 'date',
    // enable 'date' control and disable 'count' control

    // if the selection value is 'count',
    // enable 'count' control and disable 'date' control
  });

结束选择器的模板看起来像这样,

<mat-select formControlName="selection">...</mat-select>

<ng-container *ngIf="selectionControl.value === 'date'">
  <!-- input with datepicker -->
</ng-container>

<ng-container *ngIf="selectionControl.value === 'count'">
  <!-- input with type="number" -->
</ng-container>

This article Todd Motto 也帮助将表单组封装到它们自己的表示组件中。我很乐意解释更多,但它绝对是我必须构建的最复杂的组件,因此包含在一个答案中有点多。

【讨论】:

  • 这很有帮助。突出的一件事是,即使在 Todd Motto 的示例中,整个组件树的 FormGroup(s) 也是在根组件中初始化的。它似乎没有我预期的那么简单,但至少它让我走上了正确的轨道。您关于enabledisable AbstractControl 的技术似乎也很关键。在标记为可接受的解决方案之前,请花一两天时间消化所有这些并进行测试。看起来很有希望。
  • 这里有一个plunkr 来展示我能够利用@WillHowell 提供的这些资源来做什么。
  • 我很高兴听到它有帮助!你的 plunker 看起来很结实。我对 Todd Motto 示例有同样的担忧……对于我们的组件,您可以以一种形式设置开始、重复和结束值,但是如果您想做比“每日”、“每周”更复杂的事情' 或 'monthly',您可以打开一个带有 miniform 的弹出框。它创建了自己的独立表单组,在提交弹出框时将其值保存回另一个表单组。如果您有幸使用带有单独提交按钮的嵌入式表单,也许您也可以使用这种方法。
猜你喜欢
  • 2019-06-12
  • 1970-01-01
  • 2020-05-13
  • 1970-01-01
  • 1970-01-01
  • 2021-01-18
  • 2011-06-17
  • 2017-12-01
  • 2017-03-07
相关资源
最近更新 更多