如何从表格的下拉菜单中删除先前选择的选项?
Posted
技术标签:
【中文标题】如何从表格的下拉菜单中删除先前选择的选项?【英文标题】:How to remove the previously selected option from a drop-down menu in a table? 【发布时间】:2019-11-15 04:45:31 【问题描述】:我正在 Angular 7 上制作一个项目。它有一个带有下拉列表的表格。下拉列表包含各种语言。在特定行中选择一种语言时,它不应出现在后续行的下拉列表中。我该怎么做?
我尝试使用 splice() 从数组中删除选定的语言。但是当它删除对象时,它也不会显示在下拉列表中。
下面是html-(它是定义下拉列表的表格的行,并且该行是动态的)
<tr *ngFor="let field of fieldArray;let i = index">
<td><button class="btn" (click)="deleteFieldValue(i)"><i class="fa fa-trash"></i></button></td>
<td class="select">
<select #selectLang (change)="selected(selectLang.value,i)">
<option value="undefined" disabled>Select Language</option>
<option *ngFor="let lang of languageList" value=lang.name [ngValue]="lang.name">lang.name</option>
</select>
</td>
<td>
<input id="fileUpload" name="fileUpload" type="file" name="upload_file" (change)=onFileChange($event)>
</td>
</tr>
以下是打字稿代码-
languageList = ['name': "Dothraki",'name': "Japanese",
'name':"German",'name':"French",'name': "Spanish", 'name':
"Russian", 'name': "Italian"];
selectedLang;
optionLang:string;
fieldArray: Array<any> = [];
newAttribute: any = ;
fileUploadName: any;
selected(lang:string,index:number)
console.log(lang);
// this.languageList.splice(index, 1);
for(let i =0; i< this.languageList.length; i++)
if(this.languageList[i]['name'] === lang)
this.languageList.splice(i,1);
break;
addFieldValue()
this.fieldArray.push("hg");
this.newAttribute = ;
deleteFieldValue(index: number)
this.fieldArray.splice(index, 1);
openFileBrowser(event:any)
event.preventDefault();
let element: HTMLElement = document.getElementById('fileUpload') as
HTMLElement;
element.click();
onFileChange(event:any)
let files = event.target.files;
this.fileUploadName = files[0].name;
console.log(files);
【问题讨论】:
【参考方案1】:您可以通过持有一组选定的语言并根据之前是否选择选项/语言有条件地显示选项来解决问题。
创建一个Set
来保存选定的语言
selectedLangs = new Set<string>();
创建视图查询以获取所有选择元素的列表
@ViewChildren("selectLang") langSelects: QueryList<ElementRef<HTMLSelectElement>>;
每当对任何选择元素进行选择/更改时,都会重新填充selectedLangs
集
selected()
this.selectedLangs.clear();
this.langSelects.forEach(ls =>
const selectedVal = ls.nativeElement.value;
if (selectedVal && selectedVal !== "undefined") this.selectedLangs.add(selectedVal);
);
每当删除一个字段时,只需从 selectedLangs
中删除该语言
deleteFieldValue(index: number, lang: string)
this.selectedLangs.delete(lang);
this.fieldArray.splice(index, 1);
当显示一个选择的选项时,检查它当前是在当前选择中选择的还是已经在另一个选择中选择*ngIf="selectLang.value === lang.name || !isSelected(lang.name)"
<ng-container *ngFor="let lang of languageList" >
<option *ngIf="selectLang.value === lang.name || !isSelected(lang.name)" value=lang.name [ngValue]="lang.name">
lang.name
</option>
</ng-container>
isSelected
定义为
isSelected(lang: string)
return this.selectedLangs.has(lang);
这是一个完整源代码的工作演示https://stackblitz.com/edit/angular-dqvvf5
【讨论】:
这有帮助,但它显示“错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'ngIf:true'。当前值:'ngIf:false'。”当我将 formcontrolname 放入选择中时。如果您使用 formcontrolname @ysf 将此代码转换为 formarray 反应形式,这会很有帮助吗【参考方案2】:您可以将语言存储在一个数组中,制作一个类似的函数
lang = []; //define the array
getLang(i, languageList)
return i == 0 ? languageList :
this.getLang(i - 1, languageList.filter(x => x.name != this.lang[i-1]))
所以,你可以有一些喜欢
<div *ngFor="let a of languageList;let i=index">
<select [(ngModel)]="lang[i]">
<option value="undefined" disabled>Select Language</option>
<option *ngFor="let lang of getLang(i,languageList)"
[value]="lang.name" >lang.name</option>
</select>
</div>
但我不喜欢,因为每次更改都会迫使 Angular 计算所有选项。所以我们将使用FormArray和数组langList来改进代码,并确保我们不能选择相同的语言
首先我们的变量和函数发生了变化
langList=[];
getLangForFormArray(i, languageList)
return i == 0 ? languageList :
this.getLang(i - 1, this.langList[i-1].filter(x => x.name != this.formArray.value[i-1]))
我们创建一个formArray
formArray=new FormArray(this.languageList.map(()=>new FormControl(null)))
在 ngOnInit 中
ngOnInit()
this.formArray.valueChanges.pipe(startWith(null)).subscribe(()=>
//create the langList array
for (let i=0;i<this.languageList.length;i++)
this.langList[i]=this.getLangForFormArray(i,this.languageList)
//check no repeat values
if (value)
value.forEach((x,index)=>
if (this.formArray.value.findIndex(v=>v==x)!=index)
this.formArray.at(index).setValue(null,emitEvent:false)
)
)
首先看到使用 formArray valueChanges 和 pipe(startWith(null)) 来创建 langList
.html
<div *ngFor="let control of formArray.controls;let i=index">
<select [formControl]="control">
<option value="null" disabled>Select Language</option>
<option *ngFor="let lang of langList[i]"
[value]="lang.name" >lang.name</option>
</select>
</div>
还有stackblitz中的demo
【讨论】:
以上是关于如何从表格的下拉菜单中删除先前选择的选项?的主要内容,如果未能解决你的问题,请参考以下文章
C# combox 设置显示下拉菜单的第一项,如图。还有下拉选项的索引怎么回事,所索引为零是菜单的第一个选项
请教Excel如何去除下拉菜单空白区域的问题,空白区域有公式。