sortablejs第二次dragStart时改变了顺序。

4

我已将sortablejs添加到我的blazor应用程序中,并且它可以工作 - 对于第一次拖放。

首先,这里是正在发生的事情:

enter image description here

Blazor组件代码:

<ul class="ulManufacturers">
    @foreach (var m in manufacturers)
    {
        var mGrayedOut = m.Visible ? "" : "grayout";
        var toggleButtonImg = showManufacturerBikes[m] ? "up" : "down";
        var toggleButtonTitle = showManufacturerBikes[m] ? $"Sakrij {m.Nickname} motore" : $"Prikaži {m.Nickname} motore";
        <li data-id="@m.Id">
            <div class="divManufacturerHeader">
                <div class="buttons">
                    <img class="zoom-on-hover cursor-grab fit-image grayout drag-handle"
                         src="/lib/bootstrap-icons-1.5.0/list.svg"
                         data-toggle="tooltip" data-placement="top"
                         title="Uhvati i premesti"/>

                    <img class="zoom-on-hover cursor-pointer fit-image grayout"
                         src="/lib/bootstrap-icons-1.5.0/plus-circle.svg"
                         data-toggle="tooltip" data-placement="top"
                         title="Dodaj novi @m.Nickname motor"
                         @onclick="()=>AddBike(m)" />

                    <img class="zoom-on-hover cursor-pointer fit-image grayout"
                         src="/lib/bootstrap-icons-1.5.0/arrow-@(toggleButtonImg)-circle.svg"
                         data-toggle="tooltip" data-placement="top"
                         title="@toggleButtonTitle"
                         @onclick="()=>ToggleBikes(m)" />
                </div>
                <div class="divLogoOrName">
                    @if (string.IsNullOrEmpty(m.LogoUrl))
                    {
                        <h1 class="zoom-on-hover cursor-pointer @mGrayedOut"
                            @onclick="()=>SelectManufacturer(m)">
                            @m.Nickname
                        </h1>
                    }
                    else
                    {
                        <img class="zoom-on-hover cursor-pointer fit-image imgManufacturerLogo @mGrayedOut"
                             src="@m.LogoUrl"
                             @onclick="()=>SelectManufacturer(m)" />
                    }
                </div>
            </div>
            <div class="divBikeThumbnailsContainer sortable-list @(showManufacturerBikes[m] ? "" : "hidden")">
                @foreach (var b in m.Bikes)
                {
                    var bGrayedOut = b.Visible ? string.Empty : "grayout";
                    <div class="sortable-list-grid-item drag-handle @bGrayedOut" @onclick="() => SelectBike(b)">
                        <img class="zoom-on-hover cursor-grab fit-image grayout"
                             src="/lib/bootstrap-icons-1.5.0/list.svg"
                             data-toggle="tooltip" data-placement="top"
                             title="Uhvati i premesti" />
                        <BikeThumbnailPage Bike="b" />
                    </div>
                }
            </div>
        </li>
    }

    @if (showButtonAddManufacturer)
    {
        <li>
            <div class="divManufacturerHeader">
                <img class="zoom-on-hover cursor-pointer fit-image grayout"
                     src="/lib/bootstrap-icons-1.5.0/plus-circle.svg"
                     data-toggle="tooltip" data-placement="top"
                     title="Dodaj novog proizvodjača"
                     @onclick="AddManufacturer" />
            </div>
        </li>
    }
</ul>

@code {

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            var objRef = DotNetObjectReference.Create(this);
            await jsRuntime.InvokeVoidAsync("EnableManufacturerSorting", objRef);
        }

        await base.OnAfterRenderAsync(firstRender);
    }


    [JSInvokable]
    public void OnManufacturerDragStart()
    {
        // hide all manufacturer bikes
        foreach (var m in manufacturers)
            showManufacturerBikes[m] = false;

        showButtonAddManufacturer = false;

        StateHasChanged();
    }

    [JSInvokable]
    public async void OnManufacturerDragEnd(int[] ids)
    {
        showButtonAddManufacturer = true;

        // set order numbers for manufacturers
        for (int orderNo = 0; orderNo < ids.Length; orderNo++)
            manufacturers
                .First(m => m.Id == ids[orderNo])
                .OrderNumber = orderNo;

        _manufacturerService.UpdateAll(manufacturers);
        //ReloadManufacturers();
        //StateHasChanged();
        //var objRef = DotNetObjectReference.Create(this);
        //await jsRuntime.InvokeVoidAsync("EnableManufacturerSorting", objRef);
    }
}

JavaScript函数在何时触发

function EnableManufacturerSorting(dotNetHelper) {

    $('.ulManufacturers').each(function() {
        new Sortable(this, {
            group: 'manufacturers',
            handle: '.drag-handle',
            direction: 'vertical',
            animation: 150,
            onStart: function () {
                console.log("onStart");
                dotNetHelper.invokeMethodAsync('OnManufacturerDragStart');
            },
            onEnd: function () {
                console.log("onEnd");
                var orderList = [];
                $(this.el).children().each(function (index, element) {
                    orderList.push($(element).data('id'));
                });
                var params = JSON.stringify({ 'orderList': orderList });
                dotNetHelper.invokeMethodAsync('OnManufacturerDragEnd', orderList);
                //dotNetHelper.dispose();
                //this.destroy();
            },
        });
    });
}

从 JS 函数和 OnManufacturerDragEnd Blazor 函数的注释中可以看出,我已尝试所有带有或不带注释代码的组合,但结果都是一样的。


更新 1

我发现如果我移除掉

// set order numbers for manufacturers
for (int orderNo = 0; orderNo < ids.Length; orderNo++)
    manufacturers
        .First(m => m.Id == ids[orderNo])
        .OrderNumber = orderNo;
    _manufacturerService.UpdateAll(manufacturers);

public async void OnManufacturerDragEnd(int[] ids) 来看,它可以正常工作,但我最终未保存新项的顺序。

如果我将其保留,但删除其他内容,则情况相同。

showButtonAddManufacturer = true;
StateHasChanged();

那意味着要么不会保存新订单,要么我无法隐藏“添加新内容”按钮(在gif底部的加号圆圈,在开始时),并将其重新显示。我怀疑 sortablejsblazor 的渲染之间存在异步性,但我还没有完全弄清楚。 “添加新内容”按钮可能与此有关。

更新2

请检查我的答案,我已经找到了一种解决方法。现在的问题是 -> 第二次拖动时到底发生了什么?如果您能向我解释发生了什么,我会接受您的答案。


更新3

我认为这是正确方向的一步。jQuery和Blazor是否可以协同工作? jQuery在我的Blazor应用程序中不能正常工作


我没有看到任何东西改变“manufacturers”中的排序。OrderBy在OrderNumber哪里? - H H
好吧,至少在服务器端不是这样的。我进行了一项测试,在没有重新激活此函数的情况下使用 dotNetHelper.dispose(); this.destroy();,结果与 gif 上的相同。制造商从数据库中重新加载,并按 OrderNumber 在函数 ReloadManufacturers() 中排序。希望我能澄清一些事情。 - Monset
1个回答

3

现在,我不确定这样做背后的原因是什么,但是我发现一个解决方法,既能保存新的顺序,又能隐藏/显示添加新按钮,就是通过jQuery而不是Blazor来隐藏/显示添加新按钮,如下:

function EnableManufacturerSorting(dotNetHelper) {
    console.log('enabled');
    $('.ulManufacturers').each(function () {
        new Sortable(this, {
            group: 'manufacturers',
            handle: '.drag-handle',
            direction: 'vertical',
            animation: 150,
            onStart: function () {
                dotNetHelper.invokeMethodAsync('OnManufacturerDragStart');
                $('.ulManufacturers .hide-while-dragging').hide(); // this line
            },
            onEnd: function () {
                var orderList = [];
                $(this.el).children().each(function (index, element) {
                    var id = $(element).data('id');
                    if (id != null)
                        orderList.push(id);
                });
                dotNetHelper.invokeMethodAsync('OnManufacturerDragEnd', orderList);
                $('.ulManufacturers .hide-while-dragging').show();  // this line
            },
        });
    });
}

当然,我还将 hide-while-dragging 类添加到 html 中的 add-new-button 的 <li>。现在,对于更复杂的情况,我想知道究竟发生了什么,所以我不会将这个标记为答案。我看到有人点赞了我的问题,这意味着我可能不是唯一一个尝试这个的人。希望有人会觉得这个有用。

我曾经遇到过sortable-js相同的情况,现在我正在编写自己的实现,您可以在这里查看https://github.com/elgransan/BlazorReorder。我知道有点晚了,但是您尝试使用非jQuery版本了吗? - Santiago
我尝试过搜索,但是没有找到像sotable-js一样“轻松、轻量级和动画效果好”的Blazor实现。也许我没有搜索足够多,也许在6个月后现在有一个很好的Blazor插件,但我不知道。感谢分享您的实现! - Monset

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接