3 votes

Sortablejs change l'ordre lors du deuxième dragStart

J'ai ajouté sortablejs à mon application blazor, et cela fonctionne - pour le premier glisser-déposer.

Tout d'abord, voici ce qui se passe :

entrer la description de l'image ici

Code du composant Blazor :

    @foreach (var m in manufacturers)
    {
        var mGrayedOut = m.Visible ? "" : "grayout";
        var toggleButtonImg = showManufacturerBikes[m] ? "up" : "down";
        var toggleButtonTitle = showManufacturerBikes[m] ? $"Hide {m.Nickname} bikes" : $"Show {m.Nickname} bikes";

                    @if (string.IsNullOrEmpty(m.LogoUrl))
                    {

                            @m.Nickname

                    }
                    else
                    {

                    }

                @foreach (var b in m.Bikes)
                {
                    var bGrayedOut = b.Visible ? string.Empty : "grayout";

                }

    }

    @if (showButtonAddManufacturer)
    {

    }

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

Fonction JavaScript qui est déclenchée sur

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

Comme vous pouvez le voir dans les commentaires de la fonction JS et de la fonction Blazor OnManufacturerDragEnd, j'ai essayé toutes les combinaisons avec ou sans code commenté, mais le résultat est le même


MISE À JOUR 1

J'ai découvert que si je supprime

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

de public async void OnManufacturerDragEnd(int[] ids), cela fonctionne bien -> mais je ne sauvegarde pas le nouvel ordre des éléments.

De même si je laisse cela, mais supprime

showButtonAddManufacturer = true;
StateHasChanged();

Cela signifie soit que je ne sauvegarderai pas le nouvel ordre, soit que je ne peux pas masquer le bouton 'ajouter nouveau' (le cercle plus au bas du gif, au début) et le ramener.

Je soupçonne qu'il y a une asynchronicité entre sortablejs et le rendu de blazor, je ne peux juste pas comprendre exactement. Le bouton 'ajouter nouveau' pourrait y être pour quelque chose


MISE À JOUR 2

Vérifiez ma réponse, j'ai trouvé une solution de contournement. La question est maintenant -> qu'est-ce qui se passe exactement lors du deuxième glisser-déposer ? Je vais accepter votre réponse si vous pouvez simplement m'expliquer ce qui se passe.


MISE À JOUR 3

Je pense que c'est la bonne direction. Est-il possible de faire fonctionner jQuery et Blazor en harmonie ? jQuery ne fonctionne pas correctement avec mon application Blazor

3voto

Monset Points 325

Maintenant, je ne connais pas exactement la raison pour laquelle cela fait ce qu'il fait, mais un contournement que j'ai trouvé, pour à la fois sauvegarder le nouvel ordre ET cacher/afficher le bouton d'ajout, est simplement de cacher/afficher le bouton d'ajout via jQuery au lieu de Blazor, comme ceci :

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(); // cette ligne
            },
            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();  // cette ligne
            },
        });
    });
}

Biensûr, j'ai aussi ajouté la classe hide-while-dragging à l'élément

  • du bouton d'ajout dans le html.

    Maintenant, pour des situations plus complexes, j'aimerais savoir exactement ce qu'il se passe afin de ne pas considérer cela comme une réponse. Je vois que quelqu'un a voté positivement pour ma question donc je ne suis probablement pas le seul à essayer ceci. J'espère que quelqu'un trouvera cela utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X