پیاده سازی جستجوی بر روی این گرید، شامل موارد زیر است:
اضافه کردن دو خاصیت جدید به کلاس PagedQueryModel سمت کلاینت جهت مشخص سازی ستونی که قرار است بر روی آن جستجو انجام شود و همچنین مقدار آن:
سپس به ProductsListComponent دو متد زیر را اضافه میکنیم:
اولی کار جستجو را انجام میدهد و دومی بازگشت حالت گرید به وضعیت اول آن است. متد getPagedProductsList قابلیت واکشی خودکار اطلاعات دو خاصیت جدیدی را که اضافه کردیم دارد و نیازی به تنظیمات اضافهتری ندارد. یعنی filterByColumn و filterByValue را به صورت خودکار به سمت سرور ارسال میکند.
پس از آن، قالب این گرید (products-list.component.html) جهت افزودن جستجو، به صورت زیر تغییر میکند:
که در آن queryModel.filterByColumn و queryModel.filterByValue از کاربر دریافت میشوند. همچنین دو متد doFilter و resetFilter را نیز فراخوانی میکند.
با این شکل:
تغییرات سمت سرور آن نیز به صورت ذیل است:
ابتدا IPagedQueryModel را با همان دو خاصیت جدید ستون فیلتر شونده و مقدار آن، تکمیل میکنیم:
از این دو خاصیت جدید، جهت افزودن متد اعمال جستجو، همانند متد ApplyOrdering که پیشتر تعریف شد، استفاده میکنیم:
در اینجا همان columnsMap مورد استفاده در متد ApplyOrdering جهت نگاشت نامهای رشتهای ستونها به معادل Expression آنها استفاده شدهاست.
در آخر، به کنترلر ProductController و اکشن متد GetPagedProducts آن مراجعه کرده و پیش از ApplyOrdering، متد جدید ApplyFiltering فوق را اضافه میکنیم:
کدهای کامل این تغییرات را از اینجا میتوانید دریافت کنید.
اضافه کردن دو خاصیت جدید به کلاس PagedQueryModel سمت کلاینت جهت مشخص سازی ستونی که قرار است بر روی آن جستجو انجام شود و همچنین مقدار آن:
export class PagedQueryModel { constructor( // ... public filterByColumn: string, public filterByValue: string, ) { } }
doFilter() { this.queryModel.page = 1; this.getPagedProductsList(); } resetFilter() { this.queryModel.page = 1; this.queryModel.filterByColumn = ""; this.queryModel.filterByValue = ""; this.getPagedProductsList(); }
پس از آن، قالب این گرید (products-list.component.html) جهت افزودن جستجو، به صورت زیر تغییر میکند:
<div class="panel panel-default"> <div class="panel-body"> <div class="form-group"> <input type="text" [(ngModel)]="queryModel.filterByValue" placeholder="Search For ..." class="form-control" /> </div> <div class="form-group"> <select class="form-control" name="filterColumn" [(ngModel)]="queryModel.filterByColumn"> <option value="">Filter by ...</option> <option *ngFor="let column of columns" [value]="column.propertyName"> {{ column.title }} </option> </select> </div> <button class="btn btn-primary" type="button" (click)="doFilter()">Search</button> <button class="btn btn-default" type="button" (click)="resetFilter()">Reset</button> </div> </div>
با این شکل:
تغییرات سمت سرور آن نیز به صورت ذیل است:
ابتدا IPagedQueryModel را با همان دو خاصیت جدید ستون فیلتر شونده و مقدار آن، تکمیل میکنیم:
public interface IPagedQueryModel { // .... string FilterByColumn { get; set; } string FilterByValue { get; set; } } public class ProductQueryViewModel : IPagedQueryModel { // ... other properties ... // ... public string FilterByColumn { get; set; } public string FilterByValue { get; set; } }
public static class IQueryableExtensions { public static IQueryable<T> ApplyFiltering<T>( this IQueryable<T> query, IPagedQueryModel model, IDictionary<string, Expression<Func<T, object>>> columnsMap) { if (string.IsNullOrWhiteSpace(model.FilterByValue) || !columnsMap.ContainsKey(model.FilterByColumn)) { return query; } var func = columnsMap[model.FilterByColumn].Compile(); return query.Where(x => func(x).ToString() == model.FilterByValue); }
در آخر، به کنترلر ProductController و اکشن متد GetPagedProducts آن مراجعه کرده و پیش از ApplyOrdering، متد جدید ApplyFiltering فوق را اضافه میکنیم:
var columnsMap = new Dictionary<string, Expression<Func<Product, object>>>() { ["productId"] = p => p.ProductId, ["productName"] = p => p.ProductName, ["isAvailable"] = p => p.IsAvailable, ["price"] = p => p.Price }; query = query.ApplyFiltering(queryModel, columnsMap); query = query.ApplyOrdering(queryModel, columnsMap);
کدهای کامل این تغییرات را از اینجا میتوانید دریافت کنید.