Как удалить ранее выбранную опцию из выпадающего меню в таблице? - PullRequest
1 голос
/ 04 июля 2019

Я делаю проект на угловой 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 голосов
/ 04 июля 2019

Вы можете сохранить langs в массиве, сделав такую ​​функцию, как

  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>

Но мне не нравится, потому что каждая сила измененияУгловой для расчета всех вариантов.Итак, мы собираемся улучшить код с помощью 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]))
  }

Мы создаемa 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

The.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

0 голосов
/ 04 июля 2019

Вы можете решить проблему, удерживая набор выбранных языков и отображая параметры условно в зависимости от того, выбран ли параметр / язык ранее или нет.

создать Set для хранения выбранных языков

selectedLangs = new Set<string>();

создать запрос представления, чтобы получить список всех выбранных элементов

@ViewChildren("selectLang") langSelects: QueryList<ElementRef<HTMLSelectElement>>;

всякий раз, когда выбор сделан / изменен на любом из элементов выбора, повторно заполните selectedLangs set

  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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...