如何从表格的下拉菜单中删除先前选择的选项?

时间:2019-07-04 12:28:25

标签: html angular typescript

我要在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);
  }

2 个答案:

答案 0 :(得分:0)

您可以通过保留一组所选语言并根据是否选择了选项/语言来有条件地显示选项来解决该问题。

创建一个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

的有效演示

答案 1 :(得分:0)

您可以将lang存储在数组中,使函数类似

  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

中的演示