Angular 材料自动完成 - 根据条件显示选项

Angular Materials auto complete - Display options based on condition

我正在使用 4 个组件,每个组件都有 material 自动完成功能,并且都具有与另一个组件相同的选项。每当我 select 组件中的一个选项 isAvailable 设置为 false 并且应该在其他组件中禁用该选项。下面是options中需要显示的数组-

Planet[] = [
    { name: "one" , distance: 100, isAvailable: true },
    { name: "two" , distance: 200, isAvailable: true},
    { name: "three" , distance: 300, isAvailable: true },
    { name: "four" , distance: 400, isAvailable: true },
    { name: "five" , distance: 500, isAvailable: true },
    { name: "six" , distance: 600, isAvailable: true },
];

我订阅了一项公共服务,该服务通过 isAvailable= true/false 为我提供了更新列表,并且有了这个新数组,我需要在自动完成中填充它。

import { Component, OnInit , Input , ViewEncapsulation} from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { CommonService } from '../common.service';
@Component({
  selector: 'falcone-traveldetails',
  templateUrl: './traveldetails.component.html',
  styleUrls: ['./traveldetails.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class TraveldetailsComponent implements OnInit {
  @Input() planets: any;

  currentPlanet: any;
  planetControl = new FormControl();
  filteredPlanet: Observable<any[]>;
  previousPlanet: any;

  constructor(private commonService:CommonService) { 
    this.commonService.planets.subscribe( data =>{
      this.planets = data;
      var filteredItems = this.planets.filter((planet:any) => {
        planet.isAvailable == true;
      })
      
    });


    this.filteredPlanet = this.planetControl.valueChanges.pipe(
      startWith(''),
      map(value => {
          return this.planets.filter((option:any) => 
        option.name?.toLowerCase().includes(value.toLowerCase()) && option.isAvailable === true );
      })
      );

      this.commonService.vehicles.subscribe( data =>{
        this.vehicles = data;
      });
  }

  ngOnInit(): void {
  }

  getPlanetName(planet: any){
    return planet ? planet.name: undefined;
  }

  onPlanetChanged(event:any){
    for(var planet of this.planets){
      if(planet.name == event.option.value.name){
        planet.isAvailable = false;
      }
      if(planet.name == this.previousPlanet?.name){
        planet.isAvailable = true;
      }
    }

    this.commonService.updatePlanetsList(this.planets);
    this.previousPlanet = event.option.value;
  }

}

组件的html-

            <mat-form-field>
                <input type="text" placeholder="Choose planet" matInput [matAutocomplete]="planetAuto" [formControl]="planetControl" [(ngModel)]="currentPlanet"/>
                <mat-autocomplete #planetAuto="matAutocomplete" [displayWith]="getPlanetName" (optionSelected)="onPlanetChanged($event)" >
                    <mat-option *ngFor="let planet of filteredPlanet | async" [value]="planet">
                     {{planet.name}}
                    </mat-option>
                </mat-autocomplete>
            </mat-form-field>

你不能在一个元素中使用 ngifngfor,所以你必须使用 ng-container。例如:

<mat-form-field>
    <input type="text" placeholder="Choose planet" matInput [matAutocomplete]="planetAuto" [formControl]="planetControl" [(ngModel)]="currentPlanet"/>
   <mat-autocomplete #planetAuto="matAutocomplete" [displayWith]="getPlanetName" (optionSelected)="onPlanetChanged($event)" >
    <ng-container *ngFor="let planet of filteredPlanet | async" >
    <mat-option *ngIf="planet.isAvailable"  [value]="planet">
        {{planet.name}}</mat-option>
    </ng-container>
   </mat-autocomplete>
</mat-form-field>