如何创建多个从同一个数组中获取值的动态下拉列表,而无需更改 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 中使用数组填充动态下拉列表的步骤