我可以使用 ViewBag 在视图和 JsonResult 方法之间交换数据吗?

Can I exchange data between view and JsonResult method using ViewBag?

我正在为 table 在我看来实现排序,它通过 ajax 调用 JsonResult 方法填充 这是我用来订购的 header link:

<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?

您的代码存在许多问题。首先 @Html.Raw(ViewBag.Sort == ...) 是剃须刀代码,在将视图发送到客户端之前在服务器上进行评估,因此您生成

<a style="cursor: pointer" onclick="getData("asc")" id="sort">Title</a>

getData("desc") 取决于最初生成视图的 GET 方法中 ViewBag.Sort 的值。没有你在哪里改变它所以你 ajax 调用总是为参数 sort.

提交相同的值

然后在 BooksData() 方法中,你有逻辑错误(尽管它们最终无关紧要)。因为你之前没有给ViewBag.Sort设置值,那么

ViewBag.Sort = ViewBag.Sort == "desc" ? "asc" : "desc";

评估为

ViewBag.Sort = null == "desc" ? "asc" : "desc";

因此 ViewBag.Sort 的值始终是 "desc",然后您的 else 块将重置为 "asc"

但是您的方法 returns 是 JsonResult,而不是视图,因此 ViewBag 值会丢失,并且它的值永远不会返回给客户端。

将视图中的代码更改为

<a href="#" style="cursor: pointer" id="sort">Title</a>

并将 ViewBag.Sort 的初始值分配给 javascript 变量,以便在您每次单击 link

时切换它
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);
    }
}

请注意,您可以在客户端执行 'sorting',而无需调用服务器的额外开销,只需使用 javascript/jquery 对 table 中的行重新排序 -请参阅 Invert table rows 示例,尽管这意味着在首次生成视图后其他用户添加到数据库的任何新记录都不会在视图中更新。