我正在使用datatablescharts。我宁愿通过模型返回标准数据,但由于某些奇怪的原因而无法返回,并且控件似乎只能与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结果相同的数据的图表返回到另一个视图,因为这是flot图表所需要的。这工作正常,但仅适用于数据的第一页。

这是控制器的操作结果:
    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>

最后,从站点复制并粘贴了相应的图表代码,仅对其进行了少许修改,因此我将其放入单独的文件中,如果您想查看完整的代码here,可以阅读很多东西,但是我看不到任何地方进行分页:
        Charts.initCharts();

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

因此,如何将其从表格中删除并传递到图表中。

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

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

之前已经做过。一个分页的表和一个图表,对应于其中显示的数据。为什么在C#MVC4中很难做到这一点。

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

很难在上面发布更多代码,我尝试了许多不同的方法,这会使发布时间变得很长。但是任何一个孤立的人或其中任何一个人都只会使问题变得混乱。

最终:我获得了一些有关如何执行此操作的线索,并开始取得进展,但是我在datatables网站上寻找的示例并不理想。这是到目前为止我进行的许多尝试之一,但操作不正确(它只是给我一个标准的数据表错误,而不是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();

但是,再次,我不知道如何使其工作。

谢谢你的帮助。

最佳答案

这真让我感到惊讶。 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>

完成此操作后,我只需要对客户端的chart.js文件做些微调整,即可通过Charts.initCharts函数获取数据,并且一切正常。

后来我遇到了匿名类型的问题,因此我尝试用适当的类(例如C#在幕后所做的事情)替换它们。但是我发现解决起来比这还容易。我的技巧是,仔细观察视图,控制器和客户端chart.js上变量的大小写。它们必须完全对应。花了我两天的时间弄乱了发现。令人惊讶的是,有时简单的更改耗时最长。

我希望其他人对此有所帮助。如果没有,发表评论,我将尝试回答。

10-07 13:30
查看更多