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'];
我是 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'];