Error with autocomplete in Angular, values are duplicated

0

I am trying to use the autocomplete of angular material, but when leaving them inside a ngFor to be dynamic (I need to create a list of items) the value of the last thing that I wrote in any of them is duplicated,

Code with the problem link

I hope someone can help me with the solution Thanks

    
asked by victor ureta 28.06.2018 в 22:23
source

1 answer

1

In your code you are using the same FormControl for all the items that are added (the value of myControl is always used). That is why it is copied in the new ones. You must use a new FormControl for each new item.

A solution can be:

In the component:

@Component({
  selector: 'autocomplete-filter-example',
  templateUrl: 'autocomplete-filter-example.html',
  styleUrls: ['autocomplete-filter-example.css']
})
export class AutocompleteFilterExample implements OnInit {

// Convertimos myControls en un array para tener nuevos FormControl's 
  myControls: FormControl[] = [new FormControl('')];
// varios = ['hola']; Ya no se necesita
  options = [
    'One',
    'Two',
    'Three'
  ];

// Tambien convertimos los filtros en array para tener filtros separados por cada control
  filteredOptions: Observable<string[]>[] = [];

  ngOnInit() {
    this.filteredOptions.push(this.myControls[0].valueChanges
      .pipe(
        startWith(''),
        map(val => this.filter(val))
      )
    );
  }

  filter(val: string): string[] {
    return this.options.filter(option =>
      option.toLowerCase().includes(val.toLowerCase()));
  }


  agregarNuevo() {
    const nuevaPos = this.myControls.push(new FormControl(""));
    this.filteredOptions.push(this.myControls[nuevaPos - 1].valueChanges
      .pipe(
        startWith(''),
        map(val => this.filter(val))
      )
    );
  }
}

In your template:

  <form class="example-form">

  <!-- myControls es un array de controles, usamos el index para saber cual filtro vamos a usar -->
  <div *ngFor="let control of myControls; let index = index">
     <mat-form-field class="example-full-width">
       <input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControls[index]" [matAutocomplete]="auto">
       <mat-autocomplete #auto="matAutocomplete">

         <!-- Usamos el index para seleccionar el filtro respectivo -->
         <mat-option *ngFor="let option of filteredOptions[index] | async" [value]="option">
           {{ option }}
         </mat-option>
       </mat-autocomplete>
     </mat-form-field>
   </div>
</form>


<button mat-raised-button (click)="agregarNuevo()">Agregar Otro Input</button>

Here is the functional code

A more elegant solution would be to create a component to contain the form and the filter. In the main component, copies would be made for each item. It would be simpler, but I show you how to do it the way you were trying.

    
answered by 02.07.2018 в 23:02