过滤掉所有其他选项时显示隐藏的 mat-option
Posted
技术标签:
【中文标题】过滤掉所有其他选项时显示隐藏的 mat-option【英文标题】:Show hidden mat-option when all the others are filtered out 【发布时间】:2021-12-29 14:20:24 【问题描述】:所以我有这个任务,我必须动态创建多个<mat-select>
s,这取决于从后端返回了多少“标签类型”。此外,<mat-select>
s 填充了数据(标签)。用户可以创建一个新的“标签类型”,这意味着需要创建一个新的<mat-select>
。 <mat-select>
s 也有一个过滤器。现在这是我卡住的地方,当过滤器过滤掉所有选项时,我需要显示一个默认的<mat-option>
来创建一个新标签(否则隐藏)。似乎没有任何效果,我尝试将(change)="onFilterChange()"
放在<mat-select>
标签上并尝试检查<mat-select>
选项的长度(从@ViewChild('select')
访问它),如果它是一个将布尔值切换为true,以显示创建标签的默认选项。然而这并没有奏效。此外,(selectionChange)
根本没有帮助我,因为在过滤选项时不会触发它。非常感谢任何帮助或见解。代码如下:
<div class="col-md-6">
<form *ngIf="preferencesFormGroup" [formGroup]="preferencesFormGroup">
<mat-form-field *ngFor="let tagType of tagTypes$ | async">
<mat-select placeholder="tagType.name" multiple #select [formControlName]="tagType.name">
<mat-select-trigger>
<mat-chip-list>
<mat-chip *ngFor="let tag of preferencesFormGroup.controls[tagType.name].value" [removable]="true"
(removed)="onTagsRemoved(tagType.name, tag)">
tag
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
</mat-chip-list>
</mat-select-trigger>
<div class="search-wrapper">
<input matInput placeholder="Search tags" [formControlName]="tagType.name + 'Search'" type="text"
id="searchInput">
<a mat-icon-button id="resetButton" (click)="clearFilter(tagType.name)">
<mat-icon aria-label="Icon-button for clearing the input" id="clearIcon" [inline]="true">clear</mat-icon>
</a>
</div>
<hr id="hrSearch">
<mat-option
*ngFor="let tag of tagType.tags | contains : preferencesFormGroup.controls[tagType.name+'Search'].value"
[value]="tag.name">tag.name</mat-option>
<mat-option *ngIf="noMoreOptions" (click)="createNewTag(tagType.name)"><i>Didn't find the tag you want? Click here to create your own.</i></mat-option>
</mat-select>
</mat-form-field>
</form>
<div class="row" style="align-items: center;">
<div class="col-md-6">
<div class="row" *ngIf="addDropDownActive" style="align-items: center;">
<div class="col-md-8">
<mat-form-field>
<input matInput placeholder="Add new preference" type="text" [(ngModel)]="newPreference">
</mat-form-field>
</div>
<div class="col-md-4">
<button mat-button mat-stroked-button color="accent" (click)="createDropdown()"
[disabled]="(newPreference === null) || (newPreference === '')">Save</button>
</div>
</div>
</div>
<div class="col-md-6">
<button mat-button (click)="switchVisible()" color="accent" class="float-right">preferenceBtn</button>
</div>
</div>
<div class="row mt-3">
<div class="col-md-6">
<button mat-button mat-stroked-button class="float-left" color="accent"
(click)="goToPreviousStep()">Back</button>
</div>
<div class="col-md-6">
<button mat-button mat-raised-button class="float-right" color="accent" (click)="goToNextStep()">Next</button>
</div>
</div>
</div>
和 .ts 文件:
@Component(
selector: 'tours-tour-tag',
templateUrl: './tour-tag.component.html',
styleUrls: ['./tour-tag.component.css']
)
export class TourTagComponent implements OnInit
tagTypes$: Observable<TagType[]>;
preferencesFormGroup: FormGroup;
addDropDownActive = false;
newPreference: string = null;
preferenceBtn = 'Create new preference';
filterPropertySearch = '';
noMoreOptions = false;
@ViewChild('select') matSelect: MatSelect;
constructor(private store: Store)
ngOnInit(): void
this.tagTypes$ = this.store.select(TagTypeSelectors.selectAllTagTypes);
this.tagTypes$.subscribe((tagTypes) => this.initForm(tagTypes) );
onTagsRemoved(tagTypeName: string, tag: string)
const tags = this.preferencesFormGroup.controls[tagTypeName].value as string[];
this.removeFirst(tags, tag);
this.preferencesFormGroup.controls[tagTypeName].setValue(tags);
private removeFirst<T>(array: T[], toRemove: T): void
const index = array.indexOf(toRemove);
if (index !== -1)
array.splice(index, 1);
switchVisible()
this.addDropDownActive = !this.addDropDownActive;
if (this.addDropDownActive)
this.preferenceBtn = 'Close';
else
this.preferenceBtn = 'Create new preference';
this.newPreference = null;
initForm(tagTypes: TagType[])
this.preferencesFormGroup = new FormGroup();
tagTypes.forEach((tagType: TagType) =>
this.preferencesFormGroup.addControl(tagType.name, new FormControl([]));
const searchFormControl = new FormControl([]);
searchFormControl.setValue('');
this.preferencesFormGroup.addControl(tagType.name + 'Search', searchFormControl);
);
console.log(this.preferencesFormGroup);
createDropdown()
const newTagType: TagType = id: null, code: null, name: this.newPreference, tags: null ;
this.store.dispatch(TagTypeActions.createTagType( tagType: newTagType ));
this.switchVisible();
clearFilter(tagTypeName: string): void
const searchControlName = tagTypeName.concat('Search');
this.preferencesFormGroup.controls[searchControlName].setValue('');
createNewTag(tagTypeName: string)
console.log('open modal component');
【问题讨论】:
【参考方案1】:问题是变量“noMoreOption”——实际上你需要一个布尔数组,而不仅仅是一个简单的变量——。但比创建一个数组更好,让 Angular 为你工作。
您可以通过<ng-container *ngIf="what-ever as items">
的方式使其成为using *ngIf to store a variable
所以,你可以使用一些类似 (*)
<ng-container *ngIf="tagType.tags | contains :
preferencesFormGroup.controls[tagType.name+'Search'].value
as items">
<mat-option *ngFor="let tag of items"
[value]="tag.name">tag.name
</mat-option>
<mat-option *ngIf="items.length==0"
(click)="createNewTag(tagType.name)">
<i>Didn't find the tag you want? Click here to create your own.</i>
</mat-option>
<ng-container>
(*)我想你的管道 contains
如果不匹配则返回一个空数组,而不是 null
【讨论】:
是的,很好,很简单,这在第一次尝试时解决了我的问题,说实话,我什至没有想到这个解决方案,我想缺乏前端经验会造成损失......非常感谢虽然我希望我能再投票几次!以上是关于过滤掉所有其他选项时显示隐藏的 mat-option的主要内容,如果未能解决你的问题,请参考以下文章