如何创建多个从同一个数组中获取值的动态下拉列表,而无需更改 Javascript 中的其他下拉列表

Posted

技术标签:

【中文标题】如何创建多个从同一个数组中获取值的动态下拉列表,而无需更改 Javascript 中的其他下拉列表【英文标题】:How to create multiple dynamic dropdowns that get values from same array without changing the others in Javascript 【发布时间】:2020-12-31 22:56:31 【问题描述】:

场景:

我有两个下拉菜单的典型场景。一个包含产品系列和其他产品系列的下拉列表。因此,您可以根据家庭选择不同的产品。

因此,每次您更改家庭(每次您在下拉菜单中选择某些内容时),第一个下拉菜单都会更改事件。

第二个下拉菜单是动态的,它会根据第一个下拉菜单加载。

let families = [
  'Foods', 'Drinks', 'Desserts'
];
let products = [];

// Change products function attached to the first dropdown
changeProducts() 
 products =  [];
 // request to server to get products or whatever depending on family
 // this._http ....
 // fill products with data

问题

¿如果我有一个按钮可以添加额外的一行两个下拉菜单会怎样?

想象一下我有一排食物 => 米饭

我想添加一个新的:

甜点 => 巧克力

当我选择甜点时,产品数组(第二个下拉列表)将变为空,不仅对于这一行,而且对于所有行,对于所有行中的所有第二个下拉列表,所以我在第一行中的第二个下拉列表的值也会改变。

我使用 Angular 来执行此操作,每次创建新行时,我都会创建以下内容:

<div class="tr-family">
      <mat-form-field>
          <mat-select formControlName="family" #r name="family" (selectionChange)="loadProductsBasedOnFamily(r.value)">
            <mat-option *ngFor="let family of families" [value]="family.idItemSubtype">
                 family.name 
            </mat-option>
        </mat-select>
    </mat-form-field>
</div>
<div class="tr-product">
    <mat-form-field>
        <mat-select formControlName="product" name="product">
            <mat-option *ngFor="let product of products"                                                                [value]="product.idItem">
                 product.name 
            </mat-option>
        </mat-select>
    </mat-form-field>
</div>

以及我用来改变它的功能:

loadProductsBasedOnFamily(idItemSubtype: string): void 
    this.products = [];
    this.allProducts.forEach(p => 
        if (p.idItemSubtype === idItemSubtype) 
            this.products.push(p);
        
    );

输出:

¿我该怎么办?如何在前几行中保留我的更改并只更改我选择的下拉菜单?

【问题讨论】:

使用id 值来确定哪个下拉列表已更改,并且只更改属于该下拉列表的第二个下拉列表。 我是怎么做到的? 你可以使用自动完成功能 所以你想要多个值? 我希望每个下拉列表的值都来自同一个数组,然后使用函数更改数组,而不是所有下拉列表中的值。 【参考方案1】:

旧答案:

如果你想这样做,你必须把它做成一个模板,这样你就可以重复使用它

@Component(
    selector: 'foods',
    template: `
            <div class="tr-family">
      <mat-form-field>
          <mat-select formControlName="family" #r name="family" (selectionChange)="loadProductsBasedOnFamily(r.value)">
            <mat-option *ngFor="let family of families" [value]="family.idItemSubtype">
                 family.name 
            </mat-option>
        </mat-select>
    </mat-form-field>
</div>
<div class="tr-product">
    <mat-form-field>
        <mat-select formControlName="product" name="product">
            <mat-option *ngFor="let product of products"                                                                [value]="product.idItem">
                 product.name 
            </mat-option>
        </mat-select>
    </mat-form-field>
</div> 
    `
)
export class FoodSelect implements OnInit 
    @Input() families: any[];
    @Input() control: FormControl;

    constructor(private foodService: FoodService) 
   
loadProductsBasedOnFamily(event)



 changeProducts() 
   products =  [];
   // request to server to get products or whatever depending on family
   // this._http ....
   // fill products with data
  


并将其用作可重用组件

新答案: 产品可以使用多级数组,可以根据行的索引来设置;

当你使用

this.products = bla bla

改成

this.products[index] = bla bla bla

【讨论】:

我希望它被选中,而不是输入。 不创建新模板就没有其他方法了吗? 您可以为新节点制作新的控件,这样每个新节点都会有不同的控件。换句话说,您将编写一个代码来复制模板并一遍又一遍地启动控件。 它是一个带有新控件的 FormArray。 您需要将产品制作成多级数组或产品列表的多个数组【参考方案2】:

您可以将值存储在 Map() 数据结构中。通过这种方式,我认为跟踪您的家人及其产品而不是使用 ID 会更容易。下面是一个简短的例子,你可以如何使用它:

var myMap = new Map();
myMap.set("Foods", ["Pizza", "Pasta", "Macaroni"]);
myMap.set("Drinks", ["Wine", "Water", "Coctails"]);
myMap.set("Desserts", ["Pancake", "Tiramissu", "Yoghurt"]);
myMap.set("Other", []); //declare empty family

myMap.get("Foods").push("Beef"); //add new product to "Foods" family
myMap.get("Other").push("ABCD", "EFGH");//push values into Other family

function loadProductsBasedOnFamily(idItemSubtype) // idItemSubtype = "Foods", "Drinks", "Desserts"...

products = myMap.get(idItemSubtype);

    console.log(products);

您还可以从数组中将系列和产品加载到地图中。有关如何在 Angular 中使用地图的更多信息:https://ng2.codecraft.tv/es6-typescript/mapset/

【讨论】:

您没有理解问题所在。如果我这样做,我会遇到同样的情况。我的第二行将修改第一行的第二个下拉列表,因为它们都从同一个数组中获取值。

以上是关于如何创建多个从同一个数组中获取值的动态下拉列表,而无需更改 Javascript 中的其他下拉列表的主要内容,如果未能解决你的问题,请参考以下文章

使用反应钩子在 REACTJS 中使用数组填充动态下拉列表的步骤

如何从数组中动态设置下拉列表的值

JavaScript 根据使用数组从另一个下拉列表中的选择动态创建选项

如何在从服务器获取数据的动态表的每一行中添加下拉列表?

使用JS动态创建国家下拉列表[重复]

如何使用带有逗号分隔值的单元格通过apps脚本创建动态下拉列表