我有一个带有传单地图的 blazor 服务器测试设置。为了使用传单,我插入了一段 JavaScript,效果很好。在传单地图的 javascript 代码中,我调用了 C# 方法:
function onMapClick(e) {
marker.setLatLng(e.latlng);
DotNet.invokeMethodAsync('TestProject', 'getCoordinatesFromLeaflet', e.latlng);
}
据我了解,C# 方法必须是静态的才能接收值。所以我在 C# / Blazor 中的方法看起来像这样(也很好用):
[JSInvokable]
public static void getCoordinatesFromLeaflet(LatLng tmp)
{
LatLng = tmp;
//InvokeAsync(StateHasChanged); doesn't work
//StateHasChanged(); doesn't work
}
在前端/ HTML 上我显示当前坐标:
<div>
Latitude: @LatLng.Lat.ToString("0.00000") , Longitude : @LatLng.Lng.ToString("0.00000") <div/>
但是前端的坐标没有更新。我必须手动重新渲染才能让他们显示最新的位置。在其他非静态函数中,我使用“InvokeAsync(StateHasChanged);”解决这个问题,但在这里我不能(CS0120)。
非静态字段、方法或属性“成员”需要对象引用
为了使用非静态字段、方法或属性,您必须 首先创建一个对象实例。有关静态的更多信息 方法,请参阅静态类和静态类成员。了解更多 有关创建类实例的信息,请参阅实例 构造函数。
我该如何解决这个问题?
我知道这已经很旧了,所以我不能将解决方案归功于此,但我通过遵循 Matthew Champion 的帖子想出了如何使用对象实例来执行此操作,并且我想分享以防其他人遇到此问题。
我没有像 Matthew 那样使用代码隐藏,所以我在 Razor 组件中完成了所有操作,然后有一个简单的 JavaScript 文件。下面是一个标准按钮的完整示例,该按钮调用 JavaScript 函数,然后调用 .Net 函数,然后重新呈现组件。这应该包含您开始使用所需的一切。
MyComponent.razor
@implements IDisposable
@inject IJSRuntime JSRuntime
<p>The number is currently set to: @_currentNumber</p>
<button onclick="CallBlazorMethod()">Counter+</button>
@code {
// Component object reference that javascript uses
private DotNetObjectReference<MyComponent>? _objRef;
private int _currentNumber;
// These get called FROM javascript
[JSInvokable]
public void BlazorMethod()
{
_currentNumber++;
StateHasChanged(); // render
}
[JSInvokable]
public void AnotherBlazorMethod()
{
// ...
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// tell JavaScript to use our object reference
_objRef = DotNetObjectReference.Create(this);
await JSRuntime.InvokeAsync<string>("SetDotNetHelper", _objRef);
if (firstRender)
{
// load anything else like normal
}
}
public void Dispose()
{
_objRef?.Dispose();
}
}
JavaScript 文件有一个函数可以设置 Component 对象引用(因此您不需要使用静态),然后可以使用该引用从 Razor 调用任何函数。
dotnet-helper.js
// set .Net object reference
function SetDotNetHelper(dotNetHelper) {
window.dotNetHelper = dotNetHelper;
}
// functions your component wants to call
function CallBlazorMethod()
{
console.log('MyComponent clicked the button');
// call .Net method using the object reference
window.dotNetHelper.invokeMethodAsync('BlazorMethod');
}
function SomeOtherFunction()
{
window.dotNetHelper.invokeMethodAsync('AnotherBlazorMethod');
}