3

我正在使用数据图表。我更愿意通过模型返回标准数据,但由于某些奇怪的原因不能,而且控件似乎只适用于 Json。也许这只是我的理解。但在这一点上,我完全迷失了。

我想做的实际上(理论上)非常简单。

操作结果 1 将具有分页数据的表作为 Json 结果返回到视图,因为这是数据表所需要的。这工作正常。

以下是控制器操作结果:

public ActionResult AjaxVitalsHandler()
{
    return PartialView();
}

[HttpPost]
[AccessRequired(AccessFeature.Vitals, AccessLevel.Read)]
public ActionResult AjaxVitalsHandler(JQueryDataTableParamModel param)
{
    int start = param.iDisplayStart;
    int perPage = Math.Min(param.iDisplayLength, 100);
    int currentPage = (start / perPage) + 1;
    int id = _accountSession.CurrentUserId;

    //...Bunch of code here to do basic queries and get the data...All working fine.

    return Json(new
    {
         sEcho = param.sEcho,
         iTotalRecords = model.TotalItemCount,
         iTotalDisplayRecords = model.TotalItemCount,
         aaData = result
    });
}

这是相应的局部视图(这是使用 RenderAction 加载到主视图中的局部视图,没什么特别的):

<table class="table table-striped table-bordered table-hover" 
                       id="vitalsTable"
                       data-request-url="@Url.Action("AjaxVitalsHandler")">
    <thead>
        <tr>
            <th class="hidden-480">Date</th>
            <th class="hidden-480">Weight (kg)</th>
            <th class="hidden-480">Height (cm)</th>
            <th class="hidden-480">BMI</th>
            <th class="hidden-480">B/P</th>
        </tr>
    </thead>
</table>

最后是相应的 DataTables 代码(由于某些奇怪的原因,当放置在部分视图中但不在主视图中时会出错,(不是我的问题,但无论如何):

<script>
    $(document).ready(function ()
    {
        var urlRequest = $('#vitalsTable').data("request-url");

        $('#vitalsTable').dataTable({
            "bSort": false,
            "bServerSide": true,
            "sAjaxSource": urlRequest,
            "sServerMethod": "POST",
            "bProcessing": true,
            "bFilter": false,
            "aLengthMenu": [[10], [10]],
            "aoColumns": [
                { "mDataProp": "VitalsDate" },
                { "mDataProp": "weight" },
                { "mDataProp": "height" },
                { "mDataProp": "bmi" },
                { "mDataProp": "bp" },
            ]
        });
    });
</script>

操作结果 2 将具有与 Json 结果相同的数据的图表返回到另一个视图,因为这是浮动图表所需要的。这工作正常,但仅适用于第一页数据。

以下是控制器操作结果:

    public ActionResult LoadVitalsChartData2()
    {
        return PartialView();
    }

    //[HttpPost]
    [AccessRequired(AccessFeature.Vitals, AccessLevel.Read)]
    public JsonResult LoadVitalsChartData()
    {
        int id = _accountSession.CurrentUserId;


        //Bunch of code here to retrieve the data...Problem here.
        //There seems to be no way to sync the Ajax call back to that it refreshes
        //the data here too.
        //Ideally what I want is that when the page button is pressed, it reloads this
        //chart too and passes to it the relevant columns of data for plotting.
        //Presently I can only get it to do the first page.
        //The queries work, but how do I pass the relevant page data from the above
        //action result so I am not just getting the first page of data every time.

        return Json(new
        {
            weightData = weightResult,
            xLabels = xAxisResult,
            heightData = heightResult

            //There is security issues around AllowGet inside a post method.
            //I would like to fix this but it is also not my question.
        }, JsonRequestBehavior.AllowGet);
    }

这是相应的局部视图(这是使用 RenderAction 加载到主视图中的局部视图,没什么特别的):

    <div id="VitalsChart" class="chart"
             data-request-url="@Url.Action("LoadVitalsChartData")">
    </div>

最后,相应的图表代码是从网站上复制和粘贴的,只是稍作修改,所以我把它放在一个单独的文件中,如果你想看到完整的代码,去这里有很多阅读,但我在任何地方都看不到做分页:

        Charts.initCharts();

显然我希望我的图表显示当前显示在表格中的数据。即,如果我的表有 100 个项目,每组 10 个,那么当我的表显示项目 20 到 30 时,我的图表应该显示这些项目的数据。它只显示第一个项目的数据 1 到 10。图表本身不需要处理分页,它只需要显示 10 个项目并知道表格何时更新。这一切都可以从发送到表的数据及其分页事件中获得。

那么如何将其从我的表格中取出并将其传递给我的图表。

我尝试将数据提取到某种数组中,以便可以共享。浮动图表不喜欢这样。我还尝试将数据提取到一个通用的操作方法并将其传递给另一个操作结果,但我不知道该怎么做。

我尝试通过定义类并将其强制转换将所有数据从匿名类型转换为标准类类型。但我仍然得到错误。

以前已经这样做过。与其中显示的数据相对应的分页表和图表。为什么这在 C# MVC4 中这么难做到。

如果有一种方法可以将上述内容与标准数据一起使用而不是 Json,我会笑的,因为我知道解决方案。事实上,我有解决方案。查询数据时,将其包装在 Paging 包装器中,以便仅返回所需的数据。然后在每个操作结果中针对同一数据集执行 2 次查询,仅将页码传递给 Paging 包装器。但是,这适用于标准 C# 和带有 EF 和 Linq 的 Razor。我的精彩控件需要 Json。这应该容易得多,但我不知道我错过了什么。

很难在这上面发布更多代码,我尝试了很多不同的方法,这会使帖子变得很长。但是任何一个孤立的或一个的任何部分都只会混淆问题。

最后:我得到了一些线索如何做到这一点并开始取得进展,但我在数据表网站上寻找的例子并不好。这是迄今为止我的许多尝试之一,但它不能正常工作(它只是给我一个标准的数据表错误,而不是一个 JavaScript 错误):

    $('#vitalsTable').live('page', function ()
    {
        var tbl = $('#vitalsTable').dataTable(
            {
                "aoColumnDefs": [{
                    "aTargets": [0],
                    "mData": function (source, type, val)
                    {
                        return "Hello";
                    }
                }]

            });

        alert("Data ==> " + tbl);

        Charts.initCharts();
    });

实际上,我想要做的是在页面更改时获取一列数据并将这些数据绘制在我的图表上。该页面包含 10 个项目。所以我应该有一列包含 10 个项目的数据,可以传递给我的图表进行绘图。

另一段代码建议我应该像上面一样检测页面更改事件,在它之前我应该​​这样做:

    var my_chart = $.plot($("#vitalsTable"), [{}]);

然后在里面我应该做这样的事情:

    my_chart.setData([new_data_set]);
    my_chart.draw();

但同样,我不知道如何使它工作。

谢谢你的帮助。

4

1 回答 1

1

这对我来说真的很令人惊讶。SO 是一个很好的资源,我喜欢它。但这是我第一次遇到 SO 用户从未回答过的问题。无论如何,终于在 8 天后,我找到了问题的答案。所以我会在这里弹出它以供将来自己参考,因为我总是回到这里。S/O 就像我的新编码圣经。

本质上控制器不是问题。甚至视图也不是问题,而是我在视图中执行 jQuery 的方式。

有人建议我在其他论坛上做类似的事情,这实际上是在我的数据表中添加了一个新的事件处理程序。

$('#vitalsTable').live('page', function ()
{
    var tbl = $('#vitalsTable').dataTable(
        {
            "aoColumnDefs": [{
                "aTargets": [0],
                "mData": function (source, type, val)
                {
                    return "Hello";
                }
            }]

        });

    alert("Data ==> " + tbl);

    Charts.initCharts();
});

在我的数据表代码中的这段代码之上,我有这样的东西:

<script>
$(document).ready(function ()
{
    var urlRequest = $('#vitalsTable').data("request-url");

    $('#vitalsTable').dataTable({
        "bSort": false,
        "bServerSide": true,
        "sAjaxSource": urlRequest,
        "sServerMethod": "POST",
        "bProcessing": true,
        "bFilter": false,
        "aLengthMenu": [[10], [10]],
        "aoColumns": [
            { "mDataProp": "VitalsDate" },
            { "mDataProp": "weight" },
            { "mDataProp": "height" },
            { "mDataProp": "bmi" },
            { "mDataProp": "bp" },
        ]
    });
});
</script>

实际上,我需要更改的只是上面的代码,下面的代码:

<script>
    $(document).ready(function ()
    {
        var urlRequest = $('#vitalsTable').data("request-url");

        $('#vitalsTable').dataTable({
            "bSort": false,
            "bServerSide": true,
            "sAjaxSource": urlRequest,
            "sServerMethod": "POST",
            "bProcessing": true,
            "bFilter": false,
            "aLengthMenu": [[10], [10]],
            "fnDrawCallback": function (oSettings)
            {
                Charts.initCharts(oSettings);
            },
            "aoColumns": [
                { "mDataProp": "VitalsDate" },
                { "mDataProp": "weight" },
                { "mDataProp": "height" },
                { "mDataProp": "bmi" },
                { "mDataProp": "bp" },
            ]
        });
    });
</script>

一旦我这样做了,我只需要对通过 Charts.initCharts 函数接收数据的客户端 chart.js 文件进行细微调整,并且一切正常。

后来我遇到了匿名类型的问题,所以我尝试用适当的类替换它们,就像 C# 在幕后所做的那样。但我发现它比这更容易解决。我的建议是,仔细观察视图、控制器和客户端 chart.js 上变量的大小写。它们必须完全对应。我花了 2 天的时间来弄明白这一点。令人惊讶的是,简单的更改有时花费的时间最长。

我希望看到这个的其他人觉得它有用。如果没有,请发表评论,我会尽力回答。

于 2013-06-07T01:07:36.047 回答