我已将sortablejs
添加到我的blazor
应用程序中,并且它可以工作 - 对于第一次拖放。
首先,这里是正在发生的事情:
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底部的加号圆圈,在开始时),并将其重新显示。我怀疑
sortablejs
和 blazor
的渲染之间存在异步性,但我还没有完全弄清楚。 “添加新内容”按钮可能与此有关。
更新2
请检查我的答案,我已经找到了一种解决方法。现在的问题是 -> 第二次拖动时到底发生了什么?如果您能向我解释发生了什么,我会接受您的答案。
更新3
我认为这是正确方向的一步。jQuery和Blazor是否可以协同工作? jQuery在我的Blazor应用程序中不能正常工作
dotNetHelper.dispose(); this.destroy();
,结果与 gif 上的相同。制造商从数据库中重新加载,并按 OrderNumber 在函数ReloadManufacturers()
中排序。希望我能澄清一些事情。 - Monset