在我的 UI 中,每一行都有 level1、level2 和 level3 下拉菜单以及“添加级别”按钮。
我想单击“添加级别”按钮,它将在同一行中添加一组新的三个下拉菜单 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] 删除。
我来说两句