【问题标题】:How to drag and drop rows with database update in ASP.NET Core using jQuery UI?如何使用 jQuery UI 在 ASP.NET Core 中通过数据库更新拖放行?
【发布时间】:2022-01-18 06:47:28
【问题描述】:

我正在使用这个 jQuery UI 库在 ASP.NET Core MVC 应用程序中拖放表格的行。

script.js

$(function(){ 
  $("#SortTable")
    .sortable({ items: "tr.sortable" })
    .dragtable({dragHandle: ".dragHandle"})
    .tablesorter();
})

cshtml

<div class="table-responsive">
    <table class="table" id="SortTable">
        <thead>
            <tr>
                <th><div class="dragHandle"></div>A</th>
                <th><div class="dragHandle"></div>B</th>
                <th><div class="dragHandle"></div>C</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var ticket in Model)
            {
                <tr class="sortable">
                    <td>@ticket.A</td>
                    <td>@ticket.B</td>
                    <td>@(ticket.C + "(" + ticket.abc + ")")</td>
                </tr>
            }
        </tbody>
    </table>
</div>

如何向控制器发送请求并更新数据库中的更改?

【问题讨论】:

  • 能否提供插件的url,我是指使用这个拖动插件的教程。
  • 这是我找到的拖放功能教程:embed.plnkr.co/twDXmS@TinyWang
  • update the changes 意思是改变数据的顺序?我不确定应该更新哪种数据
  • 更新显示顺序的变化。例如: CurrentDisplayOrder={1,2,3,4,5} ChangedDisplayOrder={2,3,1,5,4} 我想按照更改后的显示顺序显示数据,仅列为 1,2,3, 4,5 但真正的顺序是 2,3,1,5,4 @TinyWang
  • 所以我们需要把每一行和它的顺序结合起来,然后发送到数据库中?

标签: jquery asp.net-mvc asp.net-core jquery-ui asp.net-core-mvc


【解决方案1】:

“在数据库级别重新排序行”总是一件棘手的事情。 Stern-Brocot 技术旨在实现对项目的重新排序,同时只需更新数据库中的一行。

斯特恩布罗科特

该理论基本上是,当使用分数时,将分子加在一起并将分母加在一起将产生一个新的分数,该分数始终位于其他两个之间:

   1 /    1 = 1
   2 /    1 = 2

Now were dragging one in between

   1 /    1 = 1
   3 /    2 = 1.5
   2 /    1 = 2

Now were adding yet another one in between

   1 /    1 = 1
   4 /    3 = 1.333
   3 /    2 = 1.5
   2 /    1 = 2

Now put another between the second and the third

   1 /    1 = 1
   5 /    4 = 1.25
   4 /    3 = 1.333
   3 /    2 = 1.5
   2 /    1 = 2

理论上这一切都很好。数字不会像其他技术那样快速飙升,并且可以轻松存储值。

不过我前段时间确实发了proof-of-concept,这清楚地表明了 Stern-brocot 技术的局限性。

虽然可以以 100% 的准确度保存数字,但数据库服务器只能以一定的“精度”进行数字计算(如果您使用带有尾数和指数的双精度数)。该演示清楚地表明,当您开始重新排序 10 件物品时,仅仅 47 次移动就已经失去了精确度(如果您尽力而为)。

Atlassian

Atlassian 有一篇关于他们如何有效处理重新排序项目的博客文章。然而 atm。我找不到它。

【讨论】:

    【解决方案2】:

    我的想法是沿着行 id 将新订单推送到一个数组中,并将该数组发送到后端,然后在您的后端您可以更新您的数据库。我也参考了这个high vote answer来实现reset order功能。

    在下面试试我的代码:

    我的控制器:

    public IActionResult Tickets()
    {
        List<TicketModel> list = new List<TicketModel>
        {
            new TicketModel{ rowid="aa", A="11",B="12",C="13",abc="hello"},
            new TicketModel{ rowid="bb", A="21",B="22",C="23",abc="world"},
            new TicketModel{ rowid="cc", A="31",B="32",C="33",abc="!!"}
        };
        return View(list);
    }
    [HttpPost]
    public string resetOrder([FromBody] List<TicketModel> postData) {
        return "success";
    }
    

    我的cshtml:

    @model IEnumerable<WebAppMvc.Models.TicketModel>
    <div class="table-responsive">
        <table class="table" id="myTable">
            <thead>
                <tr>
                    <th><div class="dragHandle"></div>A</th>
                    <th><div class="dragHandle"></div>B</th>
                    <th><div class="dragHandle"></div>C</th>
                </tr>
            </thead>
            <tbody>
                @{int i = 1;}
                @foreach (var ticket in Model)
                {
                <tr class="sortable">
                    <td class="index" id="@ticket.rowid">@i</td>
                    @{i++;}
                    <td>@ticket.A</td>
                    <td>@ticket.B</td>
                    <td>@(ticket.C + "(" + ticket.abc + ")")</td>
                </tr>
                }
            </tbody>
        </table>
        <button id="updateBtn">update</button>
    </div>
    @section scripts{
        <script src="~/js/jquery.ui.js"></script>
        <script src="~/js/jquery.dragtable.js"></script>
        <script src="~/js/jquery.tablesorter.min.js"></script>
        <script>
            $(function () {
                var reslist = [];
                var fixHelperModified = function (e, tr) {
                    var $originals = tr.children();
                    var $helper = tr.clone();
                    $helper.children().each(function (index) {
                        $(this).width($originals.eq(index).width())
                    });
                    return $helper;
                },
                    updateIndex = function (e, ui) {
                        $('td.index', ui.item.parent()).each(function (i) {
                            //$(this).html(i + 1);
                            var data = new Object();
                            data.rowid = $(this).attr("id");
                            data.order = (i + 1).toString();
                            reslist.push(data);
                            console.info(reslist);
                        });
    
                        
                    };
                $("#myTable")
                    .sortable({
                        items: "tr.sortable",
                        helper: fixHelperModified,
                        stop: updateIndex
                    })
                    .dragtable({ dragHandle: ".dragHandle" })
                    .tablesorter();
            });
            $('#updateBtn').click(function(){
               $.ajax({
                            url: "/home/resetOrder",
                            data: JSON.stringify(reslist),
                            type: "post",
                            dataType: "json",
                            contentType: "application/json; charset=utf-8",
                            success: function (data) {
                                reslist = [];
                            }
                        });
            });
        </script>
    }
    

    我的模特:

    public class TicketModel
        {
            public string rowid { get; set; }
            public string A { get; set; }
            public string B { get; set; }
            public string C { get; set; }
            public string abc { get; set; }
            public string order { get; set; }
        }
    

    【讨论】:

    • 因此,只需注释$(this).html(i + 1); 的行代码,使其不改变索引。然后,您可以在单击事件时将 ajax 请求移动到按钮,以便在单击按钮时触发更新。然后在您的后端,您获得了数据,您使用 EF Core 更新数据库不受此更改的影响。
    猜你喜欢
    • 2022-09-24
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 2013-12-30
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    相关资源
    最近更新 更多