Можно ли обмениваться данными между представлением и методом JsonResult, используя ViewBag?
Я реализую сортировку для таблицы в моем представлении, где она заполняется через вызов ajax JsonResult
Метод, это ссылка на заголовок, которую я использую для заказа:
<a style="cursor: pointer" onclick="getData('@Html.Raw(ViewBag.Sort == "asc" ? "desc" : "asc")')" id="sort">Title</a>
JsonResult
метод:
public JsonResult BooksData(string sort)
{
ViewBag.Sort = ViewBag.Sort == "desc" ? "asc" : "desc";
var books = new List<Book>();
if (sort == "asc")
{
books = db.Books.Include(b => b.Author).OrderBy(b => b.Title).ToList();
ViewBag.Sort = "desc";
}
else
{
books = db.Books.Include(b => b.Author).OrderByDescending(b => b.Title).ToList();
ViewBag.Sort = "asc";
}
return Json(books, JsonRequestBehavior.AllowGet);
}
getsData
функция:
function getData(sort) {
var srt = sort;
$('#tbl>tbody').empty();
$.ajax({
type: 'GET',
url: '/Book/BooksData?sort=' + srt,
dataTtype: 'json',
success: function (data) {
$.each(data, function (index, val) {
$('#tbl>tbody').append('<tr><td>' + val.Title + '</td><td>' + val.Author.Name + '</td></tr>')
});
}
});
}
но ценность ViewBag.Sort
всегда asc
?
1 ответ
Есть много проблем с вашим кодом. Первый @Html.Raw(ViewBag.Sort == ...)
является бритвенным кодом и оценивается на сервере перед отправкой представления клиенту
<a style="cursor: pointer" onclick="getData("asc")" id="sort">Title</a>
или же getData("desc")
в зависимости от стоимости ViewBag.Sort
в методе GET, который изначально генерировал представление. Нет, где вы когда-либо меняете его, поэтому ваш ajax-вызов всегда отправляет одно и то же значение для параметра sort
,
Тогда в BooksData()
Метод, у вас есть логические ошибки (хотя они в конечном итоге не имеют значения). Поскольку вы ранее не устанавливали значение для ViewBag.Sort
, затем
ViewBag.Sort = ViewBag.Sort == "desc" ? "asc" : "desc";
оценивает
ViewBag.Sort = null == "desc" ? "asc" : "desc";
поэтому ценность ViewBag.Sort
всегда "desc"
какой твой else
затем блок сбрасывается "asc"
,
Но ваш метод возвращает JsonResult
, а не вид, поэтому ViewBag
затем значение теряется, и его значение никогда не возвращается клиенту.
Измените свой код в представлении на
<a href="#" style="cursor: pointer" id="sort">Title</a>
и назначить начальное значение ViewBag.Sort
в переменную javascript, чтобы ее можно было переключать при каждом нажатии на ссылку
var currentSort = '@Html.Raw(ViewBag.Sort)'
var url = '@Url.Action("BooksData", "Book")';
// handle the click event of the link
$('#sort').click(function() {
// toggle the value
currentSort = currentSort == 'acs' ? 'desc' : 'asc';
$('#tbl>tbody').empty();
$.getJSON(url, { sort: currentSort }, function(data) {
$.each(data, function (index, val) {
.... // append table rows
});
});
});
и метод контроллера тогда
public JsonResult BooksData(string sort)
{
if (sort == "asc")
{
var books = db.Books.Include(b => b.Author).OrderBy(b => b.Title); // no need for .ToList()`
return Json(books, JsonRequestBehavior.AllowGet);
}
else
{
var books = db.Books.Include(b => b.Author).OrderByDescending(b => b.Title);
return Json(books, JsonRequestBehavior.AllowGet);
}
}
Обратите внимание, что вы можете выполнить "сортировку" на клиенте без дополнительных затрат на вызов сервера, просто переупорядочив строки в таблице с помощью javascript/jquery - для примера обратитесь к инвертированным строкам таблицы, хотя это означает, что любой новые записи, добавленные в базу данных другими пользователями после первого создания представления, не будут обновляться в представлении.