Ответ 1
Проверьте DataTables @DataTables Это позволит вам распечатать результат и запросить его с легкой настройкой. он хорошо работает с данными ajax и json. Посмотрите на образцы. Надеюсь, это поможет вам.
Мне было интересно, как люди собираются сортировать таблицу в asp.net mvc? Я слышал о решениях javascript, которые очень хорошо работают с таблицами без подкачки, такими как сортировщик таблицы jQuery, но мне нужно решение, которое будет работать с выгруженными таблицами.
В проекте, над которым я работаю, в настоящее время используется следующее решение, но я нахожу его очень грязным.
контроллер
public ActionResult Sort(string parameter)
{
IEnumerable<IProduct> list;
if (Session["Model"] != null)
list = (IEnumerable<IProduct>)Session["Model"]).ToList<IProduct>();
else
list = _service.GetAll();
if (Session["parameter"] == null && Session["sortDirection"] == null)
{
//set the parameter and set the sort to desc
Session["parameter"] = parameter;
Session["sortDirection"] = "DESC";
}
else if (Session["parameter"] != null) //already set so not the first time
{
//same parameter sent
if (Session["parameter"].ToString().Equals(parameter))
{
//check sort direction and reverse
if (Session["sortDirection"].ToString().Equals("DESC"))
Session["sortDirection"] = "ASC";
else
Session["sortDirection"] = "DESC";
}
else //different parameter sent
{
Session["sortDirection"] = "DESC";
Session["parameter"] = parameter;
}
}
if (Session["sortDirection"].CompareTo("ASC") == 0)
list = Models.ContollerHelpers.SortingHelper.OrderBy(list.AsQueryable(), column);
else
list = Models.ContollerHelpers.SortingHelper.OrderByDescending(list.AsQueryable(), column);
return View("Results", list.ToList);
}
Помощник
public class Helper()
{
private static IOrderedQueryable<T> OrderingHelper<T>(IQueryable<T> source, string propertyName, bool descending, bool anotherLevel)
{
ParameterExpression param = Expression.Parameter(typeof(T), string.Empty); // I don't care about some naming
MemberExpression property = Expression.PropertyOrField(param, propertyName);
LambdaExpression sort = Expression.Lambda(property, param);
MethodCallExpression call = Expression.Call(
typeof(Queryable),
(!anotherLevel ? "OrderBy" : "ThenBy") + (descending ? "Descending" : string.Empty),
new[] { typeof(T), property.Type },
source.Expression,
Expression.Quote(sort));
return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
}
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
return OrderingHelper(source, propertyName, false, false);
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string propertyName)
{
return OrderingHelper(source, propertyName, true, false);
}
public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName)
{
return OrderingHelper(source, propertyName, false, true);
}
public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string propertyName)
{
return OrderingHelper(source, propertyName, true, true);
}
}
Просмотр списка
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Models.Interface.IProduct>>" %>
<% Session["model"] = Model; %>
<table>
<tr>
<th>
Edit Details
</th>
<th>
<%=Html.ActionLink("Id","Sort",new {parameter ="Id"}) %>
</th>
<th>
<%=Html.ActionLink("Name", "Sort", new { parameter = "Name"})%>
</th>
<th>
<%=Html.ActionLink("Status", "Sort", new { parameter = "Status" })%>
</th>
<th>
<%=Html.ActionLink("Notes", "Sort", new { parameter = "Notes"})%>
</th>
</tr>
<% foreach (var item in Model){ %>
<tr>
<td>
<%= Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> |
</td>
<td>
<%= Html.Encode(item.Id) %>
</td>
<td>
<%= Html.Encode(item.Name) %>
</td>
<td>
<%= Html.Encode(item.Status) %>
</td>
<td>
<%= Html.Encode(item.Notes) %>
</td>
</tr>
<% } %>
</table>
Это единственный способ сделать что-то подобное? Если кто-то знает более хороший способ, который не включает в себя одновременное загрузку всех записей на страницу, обратитесь к примерам.
Проверьте DataTables @DataTables Это позволит вам распечатать результат и запросить его с легкой настройкой. он хорошо работает с данными ajax и json. Посмотрите на образцы. Надеюсь, это поможет вам.
Попробуйте следующие методы расширения (сверху):
static class OrderByExtender
{
public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> collection, string key, string direction)
{
LambdaExpression sortLambda = BuildLambda<T>(key);
if(direction.ToUpper() == "ASC")
return collection.OrderBy((Func<T, object>)sortLambda.Compile());
else
return collection.OrderByDescending((Func<T, object>)sortLambda.Compile());
}
public static IOrderedEnumerable<T> ThenBy<T>(this IOrderedEnumerable<T> collection, string key, string direction)
{
LambdaExpression sortLambda = BuildLambda<T>(key);
if (direction.ToUpper() == "ASC")
return collection.ThenBy((Func<T, object>)sortLambda.Compile());
else
return collection.ThenByDescending((Func<T, object>)sortLambda.Compile());
}
private static LambdaExpression BuildLambda<T>(string key)
{
ParameterExpression TParameterExpression = Expression.Parameter(typeof(T), "p");
LambdaExpression sortLambda = Expression.Lambda(Expression.Convert(Expression.Property(TParameterExpression, key), typeof(object)), TParameterExpression);
return sortLambda;
}
}
Использование:
var products = Session["Model"] as IEnumerable<Product>() ?? _service.GetAll();
return products.OrderBy("Name", "ASC").ThenBy("Price", "DESC");
Предполагая, что вы используете только одно условие orderby за время, которое вы можете использовать:
var products = Session["Model"] as IEnumerable<Product>();
var sortDirection = Session["Direction"] as string ?? "DESC";
Session["Direction"] = sortDirection == "DESC" ? "ASC" : "DESC";
sortDirection = Session["Direction"] as string;
return products.OrderBy(parameter, sortDirection);
Если JavaScript отключен, у вас возникла проблема.
Я бы выбрал решение noscript.
У меня было бы две группы переключателей:
direction: ( ) ascending (.) descending
orderBy: (.) Id ( ) Name ( ) Status
Я бы рассматривал Вид как форму с несколькими кнопками отправки:
(без JavaScript) ~ то же имя для обеих кнопок.
на вашей странице .aspx добавьте три кнопки:
<input type="submit" value="Requery" name="submitButton"/>
<input type="submit" value="Previous" name="submitButton"/>
<input type="submit" value="Next" name="submitButton"/>
в контроллере:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Sort(string direction, string orderBy, string submitButton)
{
if (submitButton == "Requery") //et cetera
TMTOWTDI: Там больше, чем один способ сделать это
Я предпочитаю описанные здесь методы: http://www.c-sharpcorner.com/UploadFile/camurphy/csharpLists03302006170209PM/csharpLists.aspx
Итак, для ex:
var products = new List<Products>();
products = ProductRepository.GetAll();
// Sort Results
products.Sort(
delegate(Products p1, Products p2) {
return p1.Name.CompareTo(p2.Name);
});
Определенно нравится Jan решение - спасибо много Ян... Вы просто сохранили мне около 60 строк кода, в которых оператор case обрабатывает каждый из заголовков столбцов. Решение "делает большой щелчок мышью, только сортировка по одному столбцу на таблицах" при использовании с двумя переменными сеанса, один для сохранения ASC/DESC в качестве логического и один для хранения имени типа/столбца.
Я использовал этот расширенный пример С# и реализовал его с VB сегодня днем. Мне удалось вырезать оператор строки из 30 строк в одну строку кода.
В ПРОСМОТРЕ:
<th>Date <a class="clickable" href="<%=Url.Action("SortStationVisits", New With {.SortField = "PlanningDate"})%>"><span class="colSort" style="display: inline-table;"></span></a></th>
РАСШИРЕНИЕ (Общий модуль OrderByExtender):
Imports System.Linq.Expressions
Public Function OrderBy(Of T)(collection As IEnumerable(Of T), key As String, isDescending As Boolean) As IOrderedEnumerable(Of T)
Dim sortLambda As LambdaExpression = BuildLambda(Of T)(key)
If isDescending Then
Return collection.OrderByDescending(DirectCast(sortLambda.Compile(), Func(Of T, Object)))
Else
Return collection.OrderBy(DirectCast(sortLambda.Compile(), Func(Of T, Object)))
End If
End Function
Public Function ThenBy(Of T)(collection As IOrderedEnumerable(Of T), key As String, isDescending As Boolean) As IOrderedEnumerable(Of T)
Dim sortLambda As LambdaExpression = BuildLambda(Of T)(key)
If (isDescending) Then
Return collection.ThenByDescending(DirectCast(sortLambda.Compile(), Func(Of T, Object)))
Else
Return collection.ThenBy(DirectCast(sortLambda.Compile(), Func(Of T, Object)))
End If
End Function
Private Function BuildLambda(Of T)(key As String) As LambdaExpression
Dim TParameterExpression As ParameterExpression = Expression.Parameter(GetType(T), "p")
Dim sortLambda As LambdaExpression = Expression.Lambda(Expression.Convert(Expression.[Property](TParameterExpression, key), GetType(Object)), TParameterExpression)
Return sortLambda
End Function
В ДЕЙСТВИИ КОНТРОЛЛЕРА:
Public Function SortStationVisits(Optional page As Integer = 1, Optional SortField As String = "") As ActionResult
Dim sps = LoadSession()
If SortField = sps.StationVisitSorter Then
sps.StationVisitDescOrder = Not (sps.StationVisitDescOrder)
Else
sps.StationVisitDescOrder = False
End If
sps.StationVisitSorter = SortField
SaveSession(sps)
Return RedirectToAction("Show")
End Function
В МЕТОДЕ ВЫБОРА КОНТРОЛЛЕРА (1 строка кода W00T!):
spv.SelectableStationVisits = spv.SelectableStationVisits.OrderBy(sps.StationVisitSorter, sps.StationVisitDescOrder).ToList