具有父子路由的反应式表单

Reactive Form with parent and child routes

我有一个数据输入表单,我正在使用 parent/child 路由器来定义呈现一些选项卡的父组件,每个选项卡加载正在编辑的实体的一部分。

例如:我有一个渲染一些选项卡的组件,每个选项卡路由到一个子路由并渲染模型的一部分(参见下面的路由)

[
  { 
    path: ':id', 
    component: ParentComponent, 
    resolve: {someModel: SomeModelResolver }, 
    children: [
      { path: '', redirectTo: 'summary', pathMatch: 'full' },
      { path: 'summary', component: SummaryComponent },
      { path: 'other', component: OtherComponent },
      ...
    ]
  }
]

我在所有子组件中使用响应式表单,但遇到了一些问题

a) 跨所有子路由访问数据(我想我可以通过 activatedRoute.parent.data 做到这一点),以及;

b) 由于 save/cancel 按钮位于父路由组件中,因此验证所有子路由的数据

有人对我如何实现这一目标有任何建议吗? (我更喜欢反应式表单解决方案而不是模板驱动表单)

如果我对你的理解正确,你有某种 "big form" 拆分成更小的、独立的形式,分布在多个延迟加载的 modules/compoents 中。您的问题是如何从所有小表格中收集数据。我想到了 4 个选项。

  1. 不要这样做并保持单一形式 - 但我假设你 cannot/dont 想这样做
  2. 到目前为止,使用路由数据传递用户填写的全部数据(恕我直言太复杂)
  3. 使用localStorage持久化每个表单
  4. 更多Angular - 在共享服务中存储部分表单数据。

如果您将所有内容存储在共享服务中(每个 child component/form 都可以访问),您的主组件将能够通过服务访问所有表单数据并组装适当的请求负载(可能). 选项 3 是我会选择的。

是否可以选择创建一个@Injectable class(服务),然后您可以将其注入所有组件以共享数据?

在此服务中,您还可以有一个保存按钮观察器,并以这种方式将事件推送到所有组件。

另一种方法在不使用路由器但 DI 的情况下非常有效,它通过 @Input 装饰器将 child formGroups 传递给 child 组件。使用 @angular/material 的 mat-accordionmat-tab-group 用非常大的形式测试了这个。性能非常好,表格可以很好地分成您想要的更小的和平。

为这些 child 表单组创建 getter 函数

get childform1() {
  return this.form.get(‘childForm1‘) as FormGroup;
}

然后只需使用

<app-childform [form]=“childform1“></app-childform>

在你的child

 @Input() form: FormGroup;

然后您可以轻松地将完整的表单保存在 parent 组件上,所有值都将很好地传递给它。