Angular Material 6x - قسمت هشتم - جستجوی کاربران توسط AutoComplete
نویسنده: وحید نصیری
تاریخ: ۱۳۹۷/۰۵/۰۱ ۹:۱۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
ng g c contact-manager/components/search-auto-complete --no-spec
import { SearchAutoCompleteComponent } from "./components/search-auto-complete/search-auto-complete.component";
@NgModule({
entryComponents: [
SearchAutoCompleteComponent
]
})
export class ContactManagerModule { }
<span fxFlex="1 1 auto"></span>
<button mat-button (click)="openSearchDialog()">
<mat-icon>search</mat-icon>
</button>
<button mat-button [matMenuTriggerFor]="menu">
<mat-icon>more_vert</mat-icon>
</button> @Component()
export class ToolbarComponent {
constructor(
private dialog: MatDialog,
private router: Router) { }
openSearchDialog() {
const dialogRef = this.dialog.open(SearchAutoCompleteComponent, { width: "650px" });
dialogRef.afterClosed().subscribe((result: User) => {
console.log("The SearchAutoComplete dialog was closed", result);
if (result) {
this.router.navigate(["/contactmanager", result.id]);
}
});
}
} namespace MaterialAspNetCoreBackend.WebApp.Controllers
{
[Route("api/[controller]")]
public class TypeaheadController : Controller
{
private readonly IUsersService _usersService;
public TypeaheadController(IUsersService usersService)
{
_usersService = usersService ?? throw new ArgumentNullException(nameof(usersService));
}
[HttpGet("[action]")]
public async Task<IActionResult> SearchUsers(string term)
{
return Ok(await _usersService.SearchUsersAsync(term));
}
}
} import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable, throwError } from "rxjs";
import { catchError, map } from "rxjs/operators";
import { User } from "../models/user";
@Injectable({
providedIn: "root"
})
export class UserService {
constructor(private http: HttpClient) { }
searchUsers(term: string): Observable<User[]> {
return this.http
.get<User[]>(`/api/Typeahead/SearchUsers?term=${encodeURIComponent(term)}`)
.pipe(
map(response => response || []),
catchError((error: HttpErrorResponse) => throwError(error))
);
}
} <h2 mat-dialog-title>Search</h2>
<mat-dialog-content>
<div fxLayout="column">
<mat-form-field class="example-full-width">
<input matInput placeholder="Choose a user" [matAutocomplete]="auto1"
(input)="onSearchChange($event.target.value)">
</mat-form-field>
<mat-autocomplete #auto1="matAutocomplete" [displayWith]="displayFn"
(optionSelected)="onOptionSelected($event)">
<mat-option *ngIf="isLoading" class="is-loading">
<mat-spinner diameter="50"></mat-spinner>
</mat-option>
<ng-container *ngIf="!isLoading">
<mat-option *ngFor="let user of filteredUsers" [value]="user">
<span>{{ user.name }}</span>
<small> | ID: {{user.id}}</small>
</mat-option>
</ng-container>
</mat-autocomplete>
</div>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button color="primary" (click)="showUser()">
<mat-icon>search</mat-icon> Show User
</button>
<button mat-button color="primary" [mat-dialog-close]="true">
<mat-icon>cancel</mat-icon> Close
</button>
</mat-dialog-actions> import { Component, OnDestroy, OnInit } from "@angular/core";
import { MatAutocompleteSelectedEvent, MatDialogRef } from "@angular/material";
import { Subject, Subscription } from "rxjs";
import { debounceTime, distinctUntilChanged, finalize, switchMap, tap } from "rxjs/operators";
import { User } from "../../models/user";
import { UserService } from "../../services/user.service";
@Component({
selector: "app-search-auto-complete",
templateUrl: "./search-auto-complete.component.html",
styleUrls: ["./search-auto-complete.component.css"]
})
export class SearchAutoCompleteComponent implements OnInit, OnDestroy {
private modelChanged: Subject<string> = new Subject<string>();
private dueTime = 300;
private modelChangeSubscription: Subscription;
private selectedUser: User = null;
filteredUsers: User[] = [];
isLoading = false;
constructor(
private userService: UserService,
private dialogRef: MatDialogRef<SearchAutoCompleteComponent>) { }
ngOnInit() {
this.modelChangeSubscription = this.modelChanged
.pipe(
debounceTime(this.dueTime),
distinctUntilChanged(),
tap(() => this.isLoading = true),
switchMap(inputValue =>
this.userService.searchUsers(inputValue).pipe(
finalize(() => this.isLoading = false)
)
)
)
.subscribe(users => {
this.filteredUsers = users;
});
}
ngOnDestroy() {
if (this.modelChangeSubscription) {
this.modelChangeSubscription.unsubscribe();
}
}
onSearchChange(value: string) {
this.modelChanged.next(value);
}
displayFn(user: User) {
if (user) {
return user.name;
}
}
onOptionSelected(event: MatAutocompleteSelectedEvent) {
console.log("Selected user", event.option.value);
this.selectedUser = event.option.value as User;
}
showUser() {
if (this.selectedUser) {
this.dialogRef.close(this.selectedUser);
}
}
}