I am a newbie to angular, and am working on getting a component in place that includes a text input field that, once more than 3 characters are entered, makes a service call to search data in a database and return an array of items that are used in a pop-up menu for selection.
I have the service in place and returning appropriately, and the menu item pops up when I want it to and goes away when I want it to, but I can't get the menu to come up with any content. It always pops up as an empty box. I was able to get mat-menu working elsewhere in my application as a context menu and that appears fine, so I'm not sure what I'm missing on this one. Anyone have any idea what's wrong?
template code:
<div>
<mat-menu #searchResultMenu="matMenu" yPosition="above" *ngIf="searchResults.length > 0">
<ng-template matMenuContent let-searchResults="searchResults">
<button mat-menu-item *ngFor="let sritem of searchResults" (click)="findAndSelect(sritem)">
{{sritem.displayName}}
</button>
</ng-template>
</mat-menu>
<!-- div below is really just there so I can open/close the menu
in typescript code rather than with a visual UI component action.
-->
<div #menuTrigger [matMenuTriggerFor]="searchResultMenu" [matMenuTriggerData]="searchResults"></div>
<mat-form-field>
<mat-label>Search String</mat-label>
<input matInput type="text" [value]="searchString" (input)="searchStringChanged($event)">
<button *ngIf="searchString" matSuffix mat-icon-button aria-label="Clear" (click)="searchString=''">
<mat-icon>clear</mat-icon>
</button>
</mat-form-field>
</div>
typeScript code:
@ViewChild(MatMenuTrigger) menuTrigger: MatMenuTrigger;
public searchResults: SearchResultItem[];
* * *
searchStringChanged(ev:Event) {
this.searchString = <string>((<any>ev.target)?.value);
if (this.searchString?.length > 3) {
this.myservice.getSearchResults(this.searchString).subscribe(data => {
<!-- prove to myself I'm getting a result set: -->
console.log("search returned results: ", data);
if (data.length > 0) {
this.searchResults = data;
this.menuTrigger.menuData = this.searchResults;
this.menuTrigger.openMenu();
}
});
}
}
clearSearchString() {
this.searchString = "";
this.searchResults = [];
this.menuTrigger.closeMenu();
}
findAndSelect(sritem: SearchResultItem) {
console.log("Searching for item named: ", sritem.displayName);
this.menuTrigger.closeMenu();
}
* * *
searchResult is an array of SearchResultItem objects returned from my service, and I've verified it is populated when the menu appears, and that each object contains a parameter called 'displayName' that is a string.
Thanks in advance.
Additional info:
what I see in the UI: UI screenshot
what I see in the debug console returned from my service: debug console screenshot
删除 let-searchResults="searchResults" ,它将起作用
While the above answered my original question, I had some other run-time errors that were popping up even though the UI was functioning fine. I eventually tracked them down and cleaned up my original post to what is below. Just thought I would add this in case anyone else was trying to copy the code I originally posted...use below instead. Basically, I removed the ngIf from my mat-menu tag and updated components accordingly in both the template and typescript, along with the original problem solution change.
Many thanks to Faizal for his comments/answer.
template code:
<div>
<mat-menu #searchResultMenu="matMenu" yPosition="above">
<ng-template matMenuContent>
<button mat-menu-item *ngFor="let sritem of searchResults" (click)="findAndSelect(sritem)">
{{sritem.displayName}}
</button>
</ng-template>
</mat-menu>
<div style="visibility: hidden; position: fixed" [matMenuTriggerFor]="searchResultMenu">
</div>
<mat-form-field>
<mat-label>Search String</mat-label>
<input matInput type="text" [value]="searchString" (input)="searchStringChanged($event)">
<button *ngIf="searchString" matSuffix mat-icon-button aria-label="Clear" (click)="searchString=''">
<mat-icon>clear</mat-icon>
</button>
</mat-form-field>
</div>
typescript code:
@ViewChild(MatMenuTrigger) searchResultMenu: MatMenuTrigger = <MatMenuTrigger><unknown>null;
public searchResults: SearchResultNode[] = [];
* * *
searchStringChanged(ev:Event) {
this.searchString = <string>((<any>ev.target)?.value);
if (this.searchString?.length > 3) {
this.myservice.getSearchResults(this.searchString).subscribe(data => {
<!-- prove to myself I'm getting a result set: -->
console.log("search returned results: ", data);
if (data.length > 0) {
this.searchResults = data;
this.searchResultMenu.menuData = this.searchResults;
this.searchResultMenu.openMenu();
}
});
}
}
clearSearchString() {
this.searchString = "";
this.searchResults = [];
this.searchResultMenu.closeMenu();
}
findAndSelect(sritem: SearchResultItem) {
console.log("Searching for item named: ", sritem.displayName);
this.searchResultMenu.closeMenu();
}
* * *
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.