我正在使用PagedList
进行服务器端分页,并且视图中还有一个用于过滤数据的文本框,以及用于确定模型中哪些字段根据搜索文本进行过滤的复选框。
我目前的代码是
查看模型
public class SearchPagingViewModels
{
public IPagedList<AllResolution> Resolutions { get; set; }
public string Keyword { get; set; } // serach text
public bool IsResYearChecked { get; set; } // used to filter the ResolutionYear field
public bool IsResNumChecked { get; set; } // used to filter the ResolutionNumber field
public bool IsResTextChecked { get; set; } // used to filter the ResolutionText field
}
控制器
public ViewResult Index(int? page string keyword, bool? isResYearChecked, bool? isResNumChecked, bool? isResTextChecked)
{
int pageSize = 25;
int pageNumber = (page ?? 1);
bool searchYear = isResYearChecked.GetValueOrDefault();
....
IQueryable<> resolutions = db.AllResolutions;
if (searchKeyword != null)
{
if (searchYear)
{
resolutions = resolutions.Where(x => x.ResolutionYear.Contains(searchKeyword));
}
....
}
resolutions = resolutions.OrderBy(c => c.ResolutionYear).ThenBy(c => c.ResolutionNumber);
SearchPagingViewModels model = new SearchPagingViewModels
{
Keyword = keyword,
IsResYearChecked = searchYear,
....
Resolutions = resolutions.ToPagedList(pageNumber, pageSize)
};
return View(model);
}
查看
@model SearchPagingViewModels
....
@using (Html.BeginForm("Index", "Resolutions", FormMethod.Get))
{
@Html.LabelFor(m => m.Keyword)
@Html.TextBoxFor(m => m.Keyword)
@Html.LabelFor(m => m.IsResYearChecked)
@Html.CheckBoxFor(m => m.IsResYearChecked)
// .. ditto for IsResNumChecked etc
<input type="submit" value="search" />
}
<table>
<thead>
....
</thead>
<tbody>
@foreach (var task in Model.Resolutions)
{
// .... build table rows
}
</tbody>
</table>
@Html.PagedListPager(Model.Resolutions, page => Url.Action("Index", new { page, Keyword = Model.Keyword, IsResYearChecked = Model.IsResYearChecked, IsResNumChecked = IsResNumChecked IsResTextChecked = Model.IsResTextChecked }))
虽然这有效,但问题是for会生成一个冗长而丑陋的查询字符串,例如
.../Index?Keyword=someText&IsResYearChecked=true&IsResYearChecked=false&IsResNumChecked=false&IsResTextChecked=true&IsResTextChecked=false
现在我想添加额外的bool
属性来过滤记录,使其更糟糕,并可能超出查询字符串限制。
有没有办法缩短网址?这会与路由有关吗?新的ViewModel是否可以实现这一目标?
答案 0 :(得分:1)
您可以使用标有bool
属性的enum
替换所有[Flags]
属性,其中enum
中的每个值代表要搜索的模型中的属性。< / p>
[Flags]
public enum FilterProperties
{
None = 0,
ResolutionYear = 1,
ResolutionNumber = 2,
ResolutionText = 4,
.... // more properties
}
,视图模型将是
public class SearchPagingViewModels
{
public string Keyword { get; set; }
public FilterProperties Filter { get; set; }
public IPagedList<AllResolution> Resolutions { get; set; }
}
然后控制器方法变为
public ViewResult Index(int? page string keyword, FilterProperties filter = FilterProperties.None)
{
IQueryable<AllResolution> resolutions = db.AllResolutions;
if (searchKeyword != null)
{
if (filter.HasFlag(FilterProperties.ResolutionYear)
{
resolutions = resolutions.Where(x => x.ResolutionYear.Contains(feyword));
}
// .... more if blocks for other enum values
}
resolutions = resolutions.OrderBy(c => c.ResolutionYear).ThenBy(c => c.ResolutionNumber);
SearchPagingViewModels model = new SearchPagingViewModels
{
Keyword = keyword,
Filter = filter,
Resolutions = resolutions.ToPagedList(pageNumber, pageSize)
};
return View(model);
}
您将查看
@using (Html.BeginForm("Index", "Resolutions", FormMethod.Get))
{
@Html.LabelFor(m => m.Keyword)
@Html.TextBoxFor(m => m.Keyword)
@Html.ValidationMessageFor(m => m.Keyword)
@Html.HiddenFor(m => m.Filter)
foreach (Enum item in Enum.GetValues(typeof(Tables.Controllers.FilterProperties)))
{
if (item.Equals(Tables.Controllers.FilterProperties.None))
{
continue;
}
<div>
<label>
<input type="checkbox" value="@((int)(object)item)" checked=@Model.Filter.HasFlag(item) />
<span>@item</span>
</label>
</div>
}
<span id="filtererror" class="field-validation-error" hidden >Please select at least one property to search</span>
<input type="submit" value="Search" />
}
<table>
....
</table>
@Html.PagedListPager(Model.Resolutions, page => Url.Action("Index", new { page, Keyword = Model.Keyword, Filter = (int)Model.Filter }))
然后使用javascript对表单.submit()
事件进行更新以更新Filter
的隐藏输入值(注意我还假设如果{{1}的值,您希望至少选中一个复选框}}不是Keyword
)
null
您的网址(基于<script>
var checkboxes = $('input:checkbox');
var keyword = $('#Keyword');
$('form').submit(function () {
var filter = 0;
// validate at least one checkbox must be checked if Keyword has a value
if (keyword.val() && checkboxes.filter(':checked').length == 0) {
$('#filtererror').show();
return false;
}
$.each(checkboxes, function () {
if ($(this).is(':checked')) {
filter += Number($(this).val());
}
// disable checkboxes to prevent their value being added to the query string
$(this).prop('disabled', true);
})
$('#Filter').val(filter);
})
checkboxes.click(function () {
if (keyword.val() && checkboxes.filter(':checked').length == 0) {
$('#filtererror').show();
} else {
$('#filtererror').hide();
}
})
</script>
和ResolutionYear
正在检查)现在将是
ResolutionText
而不是
.../Index?Keyword=someText&Filter=5