带有显示部分的复选框的角度表单

问题描述 投票:0回答:1

对这可能是一个简单的问题表示歉意,但作为一名试图编写 Angular 的产品经理,我的头撞到了墙上。

我想要创建的是一个具有条件部分的 Angular 形式。有一个初始复选框:是否应该收集条目信息?

基于此检查,它应该打开下一部分:条目类别

在入门类别中有四个选项:苹果、香蕉、橙子、猕猴桃

如果选择了条目类别中的四个选项中的任何一个,则应打开下一部分:条目详细信息并且与该类别相关的条目详细信息应显示选项。

所有条目详细信息都是相同的,它们有一个复选框:有机、转基因、乐高和带有占位符的输入:水果名称

因此,如果在条目类别中选择了 Apple,则应打开条目详细信息并显示以下复选框:有机、转基因、乐高;和水果名称输入。

我已经能够将第一个复选框中的条件放入条目类别中,这就是它变得危险的地方。我最初的尝试是使用 formControlNames 以及与 ngModel 相关的每个复选框的编译。它也非常复杂。然后我做了一些巨大的更改以从 ts 文件中的数组中提取数据。

我遇到了以下问题:

  1. 对于 ts 文件中的所有选项,我如何获取最后一个选项并将其作为输入?
  2. 我默认选中了“联系人”,但实际上并没有将其标记为选中,有什么办法吗?
  3. 有没有办法将条目详细信息保留在顶部部分并将结果推送到单独的部分?

我原来的入口html和ts文件: 入口.组件.html

 <div fxlayout="row" fxLayoutalign="start center" class="padded-bottom">
  <mat-checkbox id="requireEntryInformation" formControlName="requireEntryInformation" [(ngModel)]="showEntryProduct">Should entry information be collected?
  </mat-checkbox>
 </div>
 <div fxLayout="column" fxLayoutalign="start center" id="entryProductCategorySection" *ngIf="showEntryProduct">
  <h2>Entry Categories</h2>
   <div fxLayout="row" fxLayoutAlign="stretch">
     <div fxFlex="50" fxFlexOffset="10" fxLayout="column" fxLayoutAlign="baseline">
      <mat-checkbox id="apple_category" [(ngModel)]="showApple">Apple</mat-checkbox>
      <mat-checkbox id="orange_category">Orange</mat-checkbox>
     </div>
     <div fxFlex="50" fxFlexOffset="10" fxLayout="column" fxLayoutAlign="baseline">
      <mat-checkbox id="kiwi_category">Kiwi</mat-checkbox>
      <mat-checkbox id="banana_category">Banana</mat-checkbox>
     </div>
    </div>
  </div>
  <div fxLayout="column" fxLayoutAlign="start center" id="entryDetailSection" *ngIf="showEntryDetailSection">
   <h2>Entry Details</h2>
    <div fxLayout="row" *ngIf="showApple">
     <h3>Apple</h3>
     <mat-checkbox>Organic</mat-checkbox>
     <mat-checkbox>GMO</mat-checkbox>
     <mat-checkbox>Lego</mat-checkbox>
    </div>
  </div>

entry.component.ts

showEntryProduct: boolean;
showApple: boolean;
defineFormGroup = () => {
 this.initializeDefaultFormValues();
 this.formGroup = this.formBuilder.group({
  requireEntryInformation: [this.defaultFormValues['requireEntryInformation'], Validators.required]
 });
}

这失败了很多,所以我构建了: StackBlitz 示例

我不知道如何处理条目数组中的输入字段。

  entries = [
    {
      name: 'Apple',
      options: ['Organic', 'GMO', 'Lego'],
      checked: false,
      field_name: 'String'
    },
    {
      name: 'Banana',
      options: ['Organic', 'GMO', 'Lego'],
      checked: false,
    },
    {
      name: 'Kiwi',
      options: ['Organic', 'GMO', 'Lego'],
      checked: false,
    },
    {
      name: 'Contact',
      options: ['Email Required?', 'Address Required?'],
      checked: true,
    },
  ];

在我的结果中,当我希望该部分完全位于 Kiwi 之后时,一旦我单击 Apple,它就会立即加载条目详细信息。 Actual Results

angular forms
1个回答
0
投票

您应该从要“存储”的“数据”开始,而不是从 .html 开始

有些喜欢

<div fxlayout="row" fxLayoutalign="start center">
  <mat-checkbox [(ngModel)]="showEntryProduct"
    >Should entry information be collected?
  </mat-checkbox>
</div>
<div *ngIf="showEntryProduct">
  <div>
    <h2>Entry Category</h2>
    <div *ngFor="let entry of entries">
      <div>
        <mat-checkbox
          [checked]="entry.checked"
          (change)="unselectRest(entry)"
          >{{ entry.name }}</mat-checkbox
        >
      </div>
    </div>
    <div *ngFor="let entry of entries">
      <div *ngIf="entry.checked">
        <div>
          <h2>Preferred {{ entry.name }}</h2>
          <mat-checkbox *ngFor="let option of entry.options">{{
            option
          }}</mat-checkbox>
        </div>
        <input mat-input [(ngModel)]="fruitName"/>
      </div>
    </div>
  </div>
</div>

在.ts中使用

  //declare also a variable fruitName
  fruitName:string="";

  unselectRest(entry:any){
      this.entries.forEach(x=>{
        x.checked=x==entry
      })
  }

显示数据(我勾选了“独占”复选框),但你无法知道选择了什么选项

如果检查的是“独占”的,我们可以稍微更改一下“entries”数组,添加一个属性:

selected

entries = [
    {
      ...
      selected:-1,
    },
    {
      ...
      selected:-1,
    },
    ....
]

然后我们还可以更改与选项相关的 mat-check

      <mat-checkbox *ngFor="let option of entry.options;let i=index" 
         [checked]="entry.selected==i"
         (change)="entry.selected=$event.checked?i:-1">
         {{option}}
      </mat-checkbox>

现在我们在“entriesArray”中拥有了所需的一切。例如,在提交中您可以使用类似的东西

submit()
{
    //find the entry checked
    const entrie=this.entries.find(x=>x.checked)

    //create an object "on fly" with the values
    const result=entrie?{name:entrie.name,
                         option:entrie.selected>=0?entrie.options[entrie.selected]:
                                                   '',
                         fruitName:this.fruitName}:null
    alert(JSON.stringify(result))
      
}

a stackblitz

注意:还有其他方法可以做,我只展示一种使用 mat-checkbox 的事件(更改)和 [checked] 属性的方法。如果您不使用材质,则可以使用一些类似的 using ngModel。也可以使用反应形式做一些类似的事情(但理念有点改变)

注意2:记住:始终首先考虑我们可以获得的数据,之后考虑.html

© www.soinside.com 2019 - 2024. All rights reserved.