2017-10-14 87 views
2

以下是Google日历的屏幕截图。我如何在Angular/Material中构建这个接口(分别为4.4.4和2.0.0-beta.12)?具有动态更改子表单的复杂角度表格

screenshot of Google Calendar Wizard for repeating events

注:有两个功能,尤其是我发现的角度和材质具有挑战性。

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

  2. “Ends:”块是一个组合单选按钮,包含某些选项的数字和日期输入。我不知道如何用角度+材质来近似,或者如何设置验证。我会满足于让“结束”也成为一个选择框,但在这种情况下,我不希望单独的组件/ formGroup用于后面的0或1输入字段。所以我不能将它完全减少到问题#1的一个实例。

+0

#1听起来像它可以通过简单的ng-if或ng-show来处理。也许你可以显示一些代码? –

回答

1

我不得不为应用程序构建相同的组件,虽然它基于OSX提醒计划程序,但它大致相同。

因为可以在整个组件中应用相同的概念,所以最好只关注“结束”选择。该end FormGroup是在一个更大的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)]] 
}) 

很显然,如果你只是提交此表作为-是,它将包含一个值,没有太大的意义。为了抵消这一点,您需要根据需要enabledisabledatecount控件。当抽象控件被禁用时,它将不包含在表单值中。

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座右铭在封装形式的群体纳入自己的表象的成分也有帮助。我很乐意解释更多,但它绝对是我必须构建的最复杂的组件,所以包含在单个答案中有点多。

+0

这非常有帮助。有一点突出的是,即使在Todd Motto的例子中,整个组件树的FormGroup都是在根组件中初始化的。它似乎比我预期的封装更少,但至少它使我走上了正确的轨道。关于'enable'和'disable'' AbstractControl'的技术似乎也是关键。在标记为可接受的解决方案之前,给我一两天的时间来消化所有这些测试。看起来很有希望。 –

+0

这是[plunkr](https://plnkr.co/edit/BzHPgW3ZKLGGpWJpHMdg),以显示我使用@WillHowell提供的这些资源所能做的事情。 –

+0

我很高兴听到它有帮助!你的运动员看起来很稳固。我对Todd Motto的例子有同样的担忧......对于我们的组件,您可以以一种形式设置开始,重复和结束值,但如果您想要执行比“每日”,“每周”或“每月”更复杂的操作,则可以打开一个弹出窗口一个miniform。它创建了它自己的独立表单组,当弹出窗口提交时,它可以将值保存回另一个表单组。如果您有使用嵌入式表单的独立提交按钮的奢侈品,也许您也可以使用该方法。 –