Можно ли обмениваться данными между представлением и методом 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 - для примера обратитесь к инвертированным строкам таблицы, хотя это означает, что любой новые записи, добавленные в базу данных другими пользователями после первого создания представления, не будут обновляться в представлении.

Другие вопросы по тегам