mat-autocomplete with filter 和 mat-table 中的选定项目不起作用

mat-autocomplete with filter and selected items in mat-table not working

我是 angular 和 angular material 的新手。我正在使用一个教程来做一个小项目,其中我有一个 angular material 自动完成来过滤演员,当我点击其中一个时,它应该显示在具有拖放功能的 mat-table 中.因此,从菜单中 - 首先单击“创建电影”以查看演员自动完成(有一个 mat-table 添加了 selected 演员)。我没有为 actors-autocomplete 的这个特性使用任何数据库,而是在代码中使用硬编码的 actors。但是在我 select 并点击它之后,自动完成中的演员并没有被添加到 mat-table 中。但是在浏览器控制台中,在我 select 一个来自自动完成的演员之后添加了一行但是没有错误 -

我在这里错过了什么。 stackblitz 中的完整 github 代码可在下面的 link 中找到。

我的整个项目在 stackblitz Project link

中可用

创建-movie.component.html

        <h2>Create Movie</h2>

    <h4>Select the Actors</h4>
    <app-actors-autocomplete></app-actors-autocomplete>

创建-movie.component.ts

      import { Component, OnInit } from '@angular/core';
  import { multipleSelectorModel } from '../../utilities/multiple-selector/multiple-selector.model';
  import { MoviesService } from '../movies.service';
  import { movieCreationDTO } from '../movies.model';
  import { map } from 'rxjs/operators';

  @Component({
    selector: 'app-create-movie',
    templateUrl: './create-movie.component.html',
    styleUrls: ['./create-movie.component.css'],
  })
  export class CreateMovieComponent implements OnInit {
    constructor() {}

   
    ngOnInit(): void {}

    saveChanges(event: Event): void {}
  }

演员-autocomplete.component.html

            <form>
        <mat-form-field>
            <input
            type="text"
            placeholder="Select the actors"
            matInput
            [formControl]="control"
            [matAutocomplete]="auto"
            />
        </mat-form-field>

        <mat-autocomplete #auto (optionSelected)="optionSelected($event)">
            <mat-option *ngFor="let actor of actorsToDisplay" [value]="actor">
            <img [src]="actor.picture" /> {{ actor.name }}
            </mat-option>
        </mat-autocomplete>
        </form>

        <table
        *ngIf="selectedActors.length > 0"
        mat-table
        [dataSource]="selectedActors"
        cdkDropList
        [cdkDropListData]="selectedActors"
        (cdkDropListDropped)="dropped($event)"
        >
        <ng-container matColumnDef="picture">
            <td mat-cell *matCellDef="let element">
            <img [src]="element.picture" style="width: 50px" />
            </td>
        </ng-container>

        <ng-container matColumnDef="name">
            <td mat-cell *matCellDef="let element">
            {{ element.name }}
            </td>
        </ng-container>
        <ng-container matColumnDef="character">
            <td mat-cell *matCellDef="let element">
            <mat-form-field appearance="outline" style="margin-top: 10px;">
                <mat-label>Character</mat-label>
                <input matInput [(ngModel)]="element.character" />
            </mat-form-field>
            </td>
        </ng-container>
        <ng-container matColumnDef="actions">
            <td mat-cell *matCellDef="let element">
            <mat-icon mat-list-icon (click)="remove(element)">close</mat-icon>
            </td>
        </ng-container>
        <tr
            mat-row
            *matRowDef="let row; columns: columnsToDisplay"
            cdkDrag
            [cdkDragData]="row"
        ></tr>
        </table>

演员-autocomplete.component.ts

        import { actorsMovieDTO } from './../actors.model';
    import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
    import { analyzeAndValidateNgModules } from '@angular/compiler';
    import { Component, Input, OnInit, ViewChild } from '@angular/core';
    import { FormControl } from '@angular/forms';
    import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
    import { MatTable } from '@angular/material/table';
    import { ActorsService } from '../actors.service';

    @Component({
      selector: 'app-actors-autocomplete',
      templateUrl: './actors-autocomplete.component.html',
      styleUrls: ['./actors-autocomplete.component.css'],
    })
    export class ActorsAutocompleteComponent implements OnInit {
      constructor(private actorService: ActorsService) {}
      control: FormControl = new FormControl();

      // @Input()
      // selectedActors : []= [];
      // actorsToDisplay:actorsMovieDTO[]=[];
      actorsToDisplay = [
        {
          name: 'Tom Holland',
          picture:
            'https://moviesapis.blob.core.windows.net/actors/bb1533c8-fe83-4145-8f8f-d1535afbe01e.jpg',
          character: '',
        },
        {
          name: 'Chris Hemsworth',
          picture:
            'https://moviesapis.blob.core.windows.net/actors/f39dd82f-5b41-4d54-887b-8430500bb0e5.jpg',
          character: '',
        },
        {
          name: 'Samuel L Jackson',
          picture:
            'https://moviesapis.blob.core.windows.net/actors/1d99e4df-dfa5-4dde-9b4b-2d197f5fb116.jpg',
          character: '',
        },
        {
          name: 'Chris Evans',
          picture:
            'https://moviesapis.blob.core.windows.net/actors/346b6791-6b61-42b7-8a57-da136463217e.jpg',
          character: '',
        },
      ];

      selectedActors: any[]=[];

      originalActors = this.actorsToDisplay;
      columnsToDisplay!: ['picture', 'name', 'character', 'actions'];
      @ViewChild(MatTable) table: MatTable<any>;

      ngOnInit(): void {
        this.control.valueChanges.subscribe((value) => {
          this.actorsToDisplay = this.originalActors;
          this.actorsToDisplay = this.actorsToDisplay.filter(
            (actor) => actor.name.indexOf(value) !== -1
          );
        });
      }

      optionSelected(event: MatAutocompleteSelectedEvent) {
        console.log(event.option.value);

        this.selectedActors.push(event.option.value);
        this.control.patchValue('');

        // this.control.patchValue('');
        if (this.table !== undefined) {
          this.table.renderRows();
        }
      }

      remove(actor) {
        const index = this.selectedActors.findIndex((a) => a.name === actor.name);
        this.selectedActors.splice(index, 1);
        this.table.renderRows();
      }

      dropped(event: CdkDragDrop<any[]>) {
        const previousIndex = this.selectedActors.findIndex(
          (actor) => actor === event.item.data
        );
        moveItemInArray(this.selectedActors, previousIndex, event.currentIndex);
        this.table.renderRows();
      }
    }

演员-autocomplete.component.css

            form{
            width:100%;
            max-width: 500px;
        }

        mat-form-field{
            width: 100%;
        }
        img{
        vertical-align: middle;
        margin-right: 8px;
        width: 35px;  
        height: 45px;
        }
        table{
            width: 100%;
            margin-bottom: 1rem;
        }

        mat-icon{
            cursor: pointer;
        }

问题出在 actors-autocomplete.component.ts 中的以下 属性 声明:

    columnsToDisplay!: ['picture', 'name', 'character', 'actions'];

应该用=初始化为:

    columnsToDisplay = ['picture', 'name', 'character', 'actions'];