J'ai ajouté sortablejs
à mon application blazor
, et cela fonctionne - pour le premier glisser-déposer.
Tout d'abord, voici ce qui se passe :
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