如何在 Angular 8 中创建动态下拉菜单

普拉维什·辛格

在我的 UI 中,每一行都有 level1、level2 和 level3 下拉菜单以及“添加级别”按钮。

我想单击“添加级别”按钮,它将在同一行中添加一组新的三个下拉菜单 level1、level2 和 level3。就像用户单击“添加级别”按钮一样,每次它都会在同一行中动态添加新的下拉列表。

其他行下拉菜单不会对此产生影响。

任何人都可以帮助修改我的旧代码以作为我的预期输出。

StackBlitz 代码 URL

请参阅所附图片,了解我对 level1 level2 和 level3 下拉菜单的预期输出

在此处输入图像描述

极乐世界

它总是一样的。要使用 ReactiveForms 控制任何对象,您可以为 Object 创建一个 FormGroup,为数组创建一个 FormArray。如果 Array 是一个对象,则创建 FormGroup 的 FormArray,否则创建 FormGroup 的 FormArray

首先是决定你的数据的结构,因为“级别”是一个数组,你的数据可以是,例如

{
  "plannedProduction": 210468,
  "factORLossTree": [
    {
      "skuid": "000000000034087070",
      "skuDescription": "SUNLIGHT DESTINY HW PWD YELLOW 8X900G",
      "productionOrderNo": "X49033251",
      "category": "Fabric Cleaning",
      "levels": [
        {
          "level1": "",
          "level2": "",
          "level3": ""
        }
        ....
      ]
    },
    {
      "skuid": "000000000067141695",
      "skuDescription": "SUNLIGHT DESTINY YELLOW 24X170G",
      "productionOrderNo": "X49039793",
      "category": "Fabric Cleaning",
      "levels": [
        {
          "level1": "",
          "level2": "",
          "level3": ""
        }
        ....
      ]
    },
    ....
   ]
}

与往常一样,你有一个 FormArray,你使用你的代码中仍然有的 getter (*)

  get lossFormArray() {
    return this.orLosstreeForm.get('factORLossTree') as FormArray;
  }

因为我们在 FormArray 中有一个 FormArray 来获取内部 FormArray,所以我们需要另一个“getter”。好吧,不能成为 getter,因为我们需要将 formArray 的“索引”作为参数传递

  getLevels(index:number)
  {
    return this.lossFormArray.at(index).get('levels') as FormArray;
  }

我们还可以使用一个辅助函数,该函数返回 index 处的 formArray 的值以简化 .html

  getItemValue(index:number)
  {
    return this.lossFormArray.at(index).value;
  }

最后我们添加一个函数来创建 formGroup “级别”

createLevel() {
    return this.fb.group({
      level1: [''],
      level2: [''],
      level3: [''],
    });

我们现在要创建 formGroup 改变一下你的函数 setData

  setData() {
    const resp = {...}
    if (resp.factORLossTree.length > 0) {
      this.orLosstreeForm.patchValue({
        plannedProduction: resp.plannedVolume,
      });
      this.lossFormArray.clear();
      for (const item of resp.factORLossTree) {
        const data = {
          skuid: item.skuid,
          skuDescription: item.skuDescription,
          productionOrderNo: item.productionOrderNo,
          category: item.category,
         
          //see how transform the data to creaate the array "levels"
          levels: [
            {
              level1: item.level1,
              level2: item.level2,
              level3: item.level3,
            },
          ],
        };
        this.addItem(this.createLevelItem(data));
      }
    }
  }

还有你的函数 cteateLevelItem:

createLevelItem(data) {
    const formgrp = this.fb.group({
      skuid: ['', Validators.required],
      ...

      //see how levels is a formArray, at first with an unique element
      //we use the before function createLevel()
      levels: this.fb.array([this.createLevel()]),
    });
    if (data !== null) {
      formgrp.patchValue(data);
    }
    return formgrp;
  }

一个复杂的部分知道是.html,但我想展示如何创建一系列互斥的下拉列表。就像这样SO,但在这种情况下,我们将有一个数组数组。别担心,让它变慢并不像看起来那么难

首先,我们有一个可能的级别并声明一个空数组

  allLevels = ['Level 1', 'Level 2', 'Level 3', 'Level 4', 'Level 5'];

  levelList: any[] = [];

然后我们将填充数组 levelList。合适的地方在函数“createLevel”中。在这个函数中,我们订阅了组的 valueChanges。但我们需要知道指数是否水平。所以函数变得像

  createLevel(index: number) {

    //we are going to create some like
    //levelList[i][j][0], levelList[i][j][1], levelList[i][j][2]

    const j = this.orLosstreeForm && 
              this.lossFormArray && 
              this.lossFormArray.at(index)?
                   this.getLevels(index).controls.length:0;
    const group = this.fb.group({
      level1: [''],
      level2: [''],
      level3: [''],
    });
    group.valueChanges
      .pipe(startWith(null), takeUntil(this.active))
      .subscribe((res: any) => {
          res = res || { level1: null, level2: null };
          if (!this.levelList[index]) this.levelList[index] = [];

          this.levelList[index][j] = [];

          this.levelList[index][j][0] = this.allLevels;
          this.levelList[index][j][1] = this.allLevels.filter(
            (x) => x != res.level1
          );
          this.levelList[index][j][2] = this.allLevels.filter(
            (x) => x != res.level1 && x != res.level2
          );

          //And we check if there any repeat

          if (this.levelList[index][j][1].indexOf(res.level2) < 0)
            group.get('level2').setValue(null, { emitEvent: false });

          if (this.levelList[index][j][2].indexOf(res.level3) < 0)
            group.get('level3').setValue(null, { emitEvent: false });
      });
    return group;
  }

噗,我知道太大了,但请耐心等待,最后一部分是.html

<div style="background-color: white;">
  <form [formGroup]="orLosstreeForm" *ngIf="orLosstreeForm">
    ...
    <!-- Start of OR loss tree table -->
    <div class="selection-area" formArrayName="factORLossTree">
      <div
        *ngFor="let levelItem of lossFormArray.controls;let i=index" [formGroupName]="i"
      >
        <ng-container>
           ...here we can use getItemValue(i).skuDescription
              or getItemValue(i).skuid or ...

                  <div class="deviations" formArrayName="levels">

                      <div class="row" *ngFor="let group of getLevels(i).controls;
        let j=index" [formGroupName]="j">
                        <div class="col-md-3">
                          <mat-form-field>
                            <mat-label>Level 1</mat-label>
                            <mat-select
                              name="level1"
                              formControlName="level1"
                            >
                              <mat-option value="">--Select--</mat-option>
                                <mat-option
                                  *ngFor="let item of levelList[i][j][0]"
                                  [value]="item"
                                >
                                  {{ item }}
                                </mat-option>
                            </mat-select>
                          </mat-form-field>
                        </div>
                        <div class="col-md-3">
                          <mat-form-field>
                            <mat-label>Level 2</mat-label>
                            <mat-select
                              name="level2"
                              formControlName="level2"
                            >
                              <mat-option value="">--Select--</mat-option>
                                <mat-option
                                  *ngFor="let item of levelList[i][j][1]"
                                  [value]="item"
                                >
                                  {{ item }}
                                </mat-option>

                            </mat-select>
                          </mat-form-field>
                        </div>
                        <div class="col-md-3">
                          <mat-form-field>
                            <mat-label>Level 3</mat-label>
                            <mat-select name="level3"
                              formControlName="level3"
                            >
                              <mat-option value="">--Select--</mat-option>

                               <mat-option
                                  *ngFor="let item of levelList[i][j][2]"
                                  [value]="item"
                                >
                                  {{ item }}
                                </mat-option>
                            </mat-select>
                          </mat-form-field>
                        </div>

                        <div class="col-md-3">
                          <button
                            class="resetButton"
                            aria-describedby="Reset SKU"
                            (click)="getLevels(i).push(createLevel(i))"
                          >
                            Add Level
                          </button>
                        </div>
                    </div>
            ....
    </div>
  </form>
</div>

看看如何添加一组新的关卡,我们只需要

<button (click)="getLevels(i).push(createLevel(i))">
    Add Level
</button>

最后的堆栈闪电

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何从Tkinter中的列表创建下拉菜单?

如何根据所选选项在所有动态创建的下拉菜单中禁用/启用选项

Angular UI Grid:如何创建用于列过滤的预填充下拉菜单

如何创建动态下拉菜单?

如何在Angular Material中创建手风琴下拉菜单?

如何在MaterializeCSS下拉菜单中创建子菜单?

如何在下拉菜单中创建子菜单(HTML / CSS)

如何在CSS中的下拉菜单上创建悬停

如何使Angular Reactive Formarray中的级联下拉菜单工作而不会弄乱下拉菜单值

如何从Django中的模型创建下拉菜单

Angular:如何在ng-bootstrap下拉菜单中检测切换状态

如何在Angular 8中循环iframe

如何在Angular 8中捕获动态渲染组件的输出?

下拉菜单以单击Angular 8的外部关闭

如何在Angular中组合两个下拉菜单时隐藏下拉菜单中的特定选项

下拉菜单无法正常工作。(Angular 8和Boostrap)

如何在Angular 8中打开自动完成功能时将选项滚动到视图中-可编辑下拉菜单

如何在Angular 8中创建和指向嵌套组件

如何在React-native中创建下拉菜单?

如何在下拉菜单中创建两列

您如何在android中创建下拉菜单答案?

如何在Bootstrap的项目菜单中创建子菜单下拉菜单?

如何在当前菜单中创建下拉菜单

如何在 ngFor 内部以 angular 8 动态执行 ngFor?

如何在 Angular 8 中触发动态创建的 http 请求列表?

如何在 Django 中创建下拉菜单?

如何在 django 中创建模型下拉菜单

如何在颤振中创建多个下拉菜单?

如何在 Swift UI 中创建下拉菜单?