Я создал простое приложение, в котором есть список продуктов и боковая панель с поисковым фильтром.(http://i.imgur.com/4tAHgiK.png) У меня возникла проблема с нумерацией страниц (с использованием PagedList
), потому что после фильтрации результатов и перехода на следующую страницу (http://i.imgur.com/xh3SSN7.png) Я получал пустую страницу. Причина была ясна. Я получал данные в параметрах действия контроллера, поэтому после нажатия кнопки «Следующая страница» данные фильтра были потеряны. Поэтому я решил где-то хранить эти данные.
Мне сказали, что мне нужна ViewModel, поэтому я создал еще одну модель FilterModel
с полями боковой панели:
public class FilterModel {
public string Manufacturer { get; set; }
public string Name { get; set; }
public int? MinPrice { get; set; }
public int? MaxPrice { get; set; }
}
а это Products
модель
public partial class Products {
[Key]
public int ProductID { get; set; }
public string Manufacturer { get; set; }
public string Name { get; set; }
......
public int Price { get; set; }
}
И поместите их в ViewModel
:
public class HomeViewModel {
public IPagedList<Products> Repository { get; set; }
public FilterModel FilterView { get; set; }
}
это мои контроллеры — HomeController
, который отображает каждый продукт, и SearchFilterController
, который должен отображать отфильтрованные продукты:
public class HomeController : Controller {
IProductRepository _repository;
public HomeController(IProductRepository rep) {
_repository = rep;
}
public ActionResult Index(int page=1) {
ViewBag.Manufacturers = Manufacturers.ManufacturersList(_repository);
var model =
(from p in _repository.Product
orderby p.Price descending
select p).ToPagedList(page, 2);
ViewBag.Title = "Home";
return View(model);
}
}
.
public class SearchFilterController : Controller {
IProductRepository _repository;
public SearchFilterController(IProductRepository rep) {
_repository = rep;
}
[HttpPost]
public ActionResult Filter(FilterModel filterModel, int page = 1) {
ViewBag.Manufacturers = Manufacturers.ManufacturersList(_repository);
var model =
(from p in _repository.Product
where (p.Manufacturer == filterModel.Manufacturer || p.Name.Contains(filterModel.Name) ||
p.Price >= filterModel.MinPrice || p.Price <= filterModel.MaxPrice)
orderby p.Price descending
select p).ToPagedList(page, 1);
ViewBag.Title = "Results";
return View(model);
}
}
В обоих контроллерах я передаю модель views
PagedList<Products>
, но они должны получить HomeViewModel
, я думаю.
вот мои взгляды: Index
(HomeController
)
@model SmartPhoneCatalog.Models.HomeViewModel
@using System.Linq
@using PagedList
@using PagedList.Mvc
@using SmartPhoneCatalog.Domain.Abstract
...
<div id="root">
@Html.Partial("_Sidebar", Model)
@Html.Partial("_ProductsList", Model)
</div>
<br>
<div class="pagedList" data-sc-target="#products">
@Html.PagedListPager(Model.Repository, page => Url.Action("Index", "Home", new { page }),
PagedListRenderOptions.ClassicPlusFirstAndLast);
</div>
Filter
(SearchFilterController
)
@model SmartPhoneCatalog.Models.HomeViewModel
@using System.Linq
@using PagedList
@using PagedList.Mvc
@using SmartPhoneCatalog.Domain.Abstract
...
<div id="root">
@Html.Partial("_Sidebar", Model)
@Html.Partial("_ProductsList", Model)
</div>
<br>
<div class="pagedList" data-sc-target="#products">
@Html.PagedListPager(Model.FilterModel, page => Url.Action("Filter", "SearchFilter", new { page }),
PagedListRenderOptions.ClassicPlusFirstAndLast);
</div>
Частичный вид: _Sidebar
@model SmartPhoneCatalog.Models.HomeViewModel
@using System.Linq
@using PagedList
@using PagedList.Mvc
<div id="filter" class="left">
@using (Html.BeginForm("Filter", "SearchFilter")) {
<div>
<b>Manufacturer:</b> <br>
<select name="manufacturer" class="form-control">
<option>@null</option>
@foreach (var item in ViewBag.Manufacturers) {
<option>@item</option>
}
</select><br>
<b>Name:</b> <br>@Html.EditorFor(model=>model.FilterModel.Name)<br>
<b>Price From:</b> <br>@Html.EditorFor(model => model.FilterModel.Name)<br>
<b>To:</b> <br>@Html.EditorFor(model => model.FilterModel.Name)<br>
<button type="submit" value="search"><b>Search</b></button>
</div>
}
</div>
Я думаю, что у меня все правильно сделано в представлениях. но я не знаю, как правильно передать им модели, а привязка объектов выполняется правильно или нет.
Какие-либо предложения?
Редактировать: Хорошо, я сделал это в контроллерах: создал объект HomeViewModel
и изменил это
var model =
(from p in _repository.Product
orderby p.Price descending
select p).ToPagedList(page, 2);
return View(model);
в это:
_homeView.Repository =
(from p in _repository.Product
orderby p.Price descending
select p).ToPagedList(page, 2);
return View(_homeView);
теперь все работает, кроме нумерации страниц после фильтрации результатов (почему я все это сделал :D). Поэтому я должен исправить привязку модели