简体   繁体   English

使用Asp.Net C#MVC4和Json,如何使我的图表更新以符合我的分页数据表

[英]Using Asp.Net C# MVC4 and Json, how can I get my chart to update in line with my paged datatable

I am using datatables and charts . 我使用的数据表图表 I would prefer to return standard data through the model but cant for some odd reason, and the controls only seem to work with Json. 我更愿意通过模型返回标准数据,但由于某些奇怪的原因,它不能用,而且控件似乎只适用于Json。 Perhaps it's just my understanding. 也许这只是我的理解。 But at this point I am completely lost. 但在这一点上,我完全迷失了。

What I want to do is actually (in theory) quite simple. 我想要做的事实上(理论上)非常简单。

Action result 1 returns a table which has paged data to a view as a Json result because that is what datatables require. 操作结果1返回一个表,该表将数据作为Json结果分页到视图,因为这是数据表所需的。 This works fine. 这很好用。

Here are the controller actionresults for this: 以下是控制器动作结果:

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
    });
}

Here is the corresponding partial view (This is a partial view loaded into a main view with RenderAction, nothing special): 这是相应的局部视图(这是用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>

Finally the corresponding DataTables code (which for some odd reason gives errors when placed in the partial view but not in the main view, (not my question but anyway): 最后是相应的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>

Action result 2 returns a chart which has the same data to another view as a Json result because that is what flot charts require. 操作结果2返回一个图表,该图表与另一个视图具有相同的数据作为Json结果,因为这是flot图表所需的。 This works fine but only for the first page of data. 这工作正常但仅适用于第一页数据。

Here are the controller actionresults for this: 以下是控制器动作结果:

    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);
    }

Here is the corresponding partial view (This is a partial view loaded into a main view with RenderAction, nothing special): 这是相应的局部视图(这是用RenderAction加载到主视图中的局部视图,没什么特别的):

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

Finally the corresponding chart code this was copied and pasted from the site and only slightly modified so I put it into a separate file, if you would like to see the full code go here there is a lot of reading but I don't see anywhere to do paging: 最后相应的图表代码这是从网站上复制和粘贴的,只是稍加修改,所以我把它放到一个单独的文件中,如果你想看到完整的代码去这里有很多阅读但我没有看到任何地方分页:

        Charts.initCharts();

Obviously I want my chart to display the data that is currently displayed in the table. 显然,我希望我的图表显示当前显示在表格中的数据。 ie if my table has 100 items paged in sets of 10, then when my table is displaying items 20 to 30, my chart should show the data for those items. 即,如果我的表有100个以10个为一组分页的项目,那么当我的表格显示项目20到30时,我的图表应显示这些项目的数据。 It only shows the data for the first items 1 to 10. The chart itself doesn't need to handle paging, it just needs the 10 items to display and to know when the table updates. 它只显示第1项到第10项的数据。图表本身不需要处理分页,它只需要显示10个项目并知道表格何时更新。 This is all available from the data sent to the table and its paging event. 这一切都可以从发送到表的数据及其分页事件中获得。

So how do get this out of my table and pass it to my chart. 那么如何从我的表中取出并将其传递给我的图表。

I have tried extracting the data to an array of some sort so it can be shared. 我已经尝试将数据提取到某种数组,以便可以共享。 flot charts doesn't like this. flot chart不喜欢这个。 I also tried extracting the data to a common action method and passing it to another actionresult but I cant figure out how to do it. 我也尝试将数据提取到一个常见的操作方法并将其传递给另一个actionresult但我无法弄清楚如何做到这一点。

I have tried converting all the data from anonymous types to standard class types by defining the class and casting it. 我已经尝试通过定义类并将其转换为将所有数据从匿名类型转换为标准类类型。 But I still get errors. 但我仍然会遇到错误。

This has been done before. 这是以前做过的。 A paged table and a chart that corresponds to the data displayed in it. 分页表和与其中显示的数据对应的图表。 Why is this so difficult to do in C# MVC4. 为什么在C#MVC4中这么难做到。

If there was a way I could use the above with standard data instead of Json, I would be laughing cause I know the solution. 如果有一种方法我可以使用上面的标准数据代替Json,我会笑,因为我知道解决方案。 In fact, I have the solution. 事实上,我有解决方案。 When querying the data, wrap it in a Paging wrapper so only the data required is returned. 查询数据时,将其包装在Paging包装器中,以便只返回所需的数据。 Then do 2 queries one in each action result for the same dataset passing only the page number to the Paging wrapper. 然后在每个操作结果中对同一数据集执行2个查询,仅将页码传递给Paging包装器。 But alas, this is for standard C# and Razor with EF and Linq. 但是,这是标准C#和Razor与EF和Linq。 My wonderful controls require Json. 我精彩的控制需要Json。 This should be a lot easier but I don't know what I am missing. 这应该更容易,但我不知道我错过了什么。

It is hard to post much more code on this, I have tried so many different ways that it would make the post very long. 很难在这上面发布更多的代码,我已经尝试了很多不同的方法,它会使帖子很长。 But any one in isolation or any part of one will serve only to confuse issues. 但任何孤立的人或任何一个人只会混淆问题。

Finally: I got some clues how to do this and started making progress but the examples I am looking for on the datatables site are not good. 最后:我得到了一些线索如何做到这一点并开始取得进展,但我在datatables网站上寻找的例子并不好。 Here is one of my many attempts so far which is not working right (it just gives me a standard datatables error, not a JavaScript error): 这是我迄今为止的许多尝试之一,它无法正常工作(它只是给我一个标准的数据表错误,而不是JavaScript错误):

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

            });

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

        Charts.initCharts();
    });

Effectively what I am looking to do, is get a column of data when the page changes and plot this data on my chart. 实际上,我希望做的是在页面更改时获取一列数据并在我的图表上绘制这些数据。 The page contains 10 items. 该页面包含10个项目。 So I should have a column of data with 10 items in it that can be passed to my chart for plotting. 所以我应该有一个包含10个项目的数据列,可以传递到我的图表进行绘图。

Another snippet of code suggests that I should detect the page change event like above and before it I should do this: 另一段代码表明我应该检测上面的页面更改事件,在此之前我应该​​这样做:

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

Then inside it I should do something like this: 然后在里面我应该做这样的事情:

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

But again, I don't know how to make it work. 但同样,我不知道如何使它发挥作用。

Thanks for any help. 谢谢你的帮助。

This is really surprising for me. 这对我来说真的很令人惊讶。 SO is a great resource, and I love it. SO是一个很好的资源,我喜欢它。 But this is the first time I came across a problem that SO users never answered. 但这是我第一次遇到SO用户从未回答的问题。 Anyway, Finally after 8 days I worked out the answer to my question. 无论如何,最后8天后我找到了问题的答案。 So I am going to pop it here for reference for myself in the future cause I always come back here. 所以我将把它放在这里供我自己参考,因为我总是回到这里。 S/O is like my new coding bible. S / O就像我的新编码圣经。

Essentially the controller was not the problem. 基本上控制器不是问题。 Even the view was not the problem but instead the way I was doing the jQuery in the view. 即使视图不是问题,而是我在视图中执行jQuery的方式。

I was advised to do something like this on other forums which essentially adds a new event handler to my data tables. 我被建议在其他论坛上做这样的事情,这实际上为我的数据表添加了一个新的事件处理程序。

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

        });

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

    Charts.initCharts();
});

Above this code in my datatables code I had something like this: 在我的数据表代码中的代码上面我有这样的东西:

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

In actuality, all I needed to change was the code directly above, to the code below: 实际上,我需要更改的是上面的代码,代码如下:

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

Once I did that, I simply needed to make minor adjustments to the client side chart.js file which takes in the data through the Charts.initCharts function and all worked well. 一旦我这样做,我只需要对客户端chart.js文件进行微调,该文件通过Charts.initCharts函数接收数据并且一切运行良好。

Later I had problems with the anonymous types, so I tried replacing them with proper classes like what C# does behind the scenes. 后来我遇到了匿名类型的问题,所以我尝试用适当的类替换它们,就像C#在幕后做的那样。 But I found that it was even easier than this to solve. 但我发现要比这更容易解决。 My tip, watch carefully the capitalisation of your variables on the view, controller and client side chart.js. 我的提示,仔细观察视图,控制器和客户端图表上的变量大小写.js。 They have to correspond exactly. 他们必须准确对应。 Took me 2 days of messing around to find that out. 花了我2天的时间来找到它。 It's surprising how simple changes sometimes take the longest. 令人惊讶的是,简单的变化有时需要花费最长的时间。

I hope others looking at this find it useful. 我希望看到这个的人发现它很有用。 If not, post a comment and I will try to answer it. 如果没有,发表评论,我会尝试回答。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何根据asp.net C#下拉菜单中的用户输入在图表上添加一条直线 - How can I add a straight line on my chart on the basis of user input from drop down menu in asp.net c# 如何在asp.net C#MVC4中的预搜索模块中处理分页? - how can i handle pagination in asp.net C# MVC4 in advance search module? ASP.NET MVC:使用我的编辑操作时,如何获得实际的 object? - ASP.NET MVC: How can I get my actual object when using my Edit action? ASP.NET MVC4 C#:获取用户角色 - ASP.NET MVC4 c# : Get user roles 使用ASP.Net MVC,Ajax和Partial Views,如何更新我的URL? - Using ASP.Net MVC, Ajax, and Partial Views, how can I update my url? 如何在linq中将多重表包含在渴望使用mvc4 C#加载的实体中 - How can I Include Multiples Tables in my linq to entities eager loading using mvc4 C# 我的ASP.NET MVC4项目中可以有一个文件夹是Webforms项目吗? - Can I have a folder in my ASP.NET MVC4 project that is a webforms project? ASP.NET MVC4表单身份验证-在对用户进行身份验证时,如何知道我的应用程序正在寻找哪个数据库? - ASP.NET MVC4 Forms Authentication - how can I tell which database my app is looking to when authenticating users? 如何将ASP.NET服务器控件添加到我的MVC4视图? - How do I add ASP.NET server controls to my MVC4 views? 我如何将数据表参数传递给我的 controller 用于我的水晶报表,以便在 ASP.Net MVC 中使用表的参数保存文件名? - How can I pass the datatable parameter to my controller for my crystal report for saving file name with parameters of the table in ASP.Net MVC?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM