【问题标题】:Blazor - User (device) geolocationBlazor - 用户(设备)地理位置
【发布时间】:2022-05-18 04:32:52
【问题描述】:

我希望可以选择在我的 blazor(服务器)应用程序上获取当前用户位置。我曾尝试使用两种解决方案 Darnton.Blazor.DeviceInterop 和 AspNetMonsters.Blazor.Geolocation。 对于第一个,我遇到了如何正确使用它的问题,第二个在 NuGet 安装后破坏了整个应用程序...... 我将不胜感激分享其他解决方案,越简单越好

【问题讨论】:

  • 您对我的包裹有什么问题?您有任何可以帮助我诊断问题的详细信息吗?
  • 我需要一个简单的例子来说明如何使用它:),假设我使用的是 NuGet 包(类似于关键的 10 行代码)

标签: blazor blazor-server-side


【解决方案1】:

如果您安装了您提到的 Blazor Geolocation 包 (Darnton.Blazor.DeviceInterop),您应该能够将 GeolocationService 与单线器一起使用:

CurrentPositionResult = await GeolocationService.GetCurrentPosition();

如果你想了解里面发生了什么,我已经写得更详细了:

https://darnton.co.nz/2020/11/29/geolocation-in-blazor/

https://darnton.co.nz/2020/11/30/geolocation-ii-position-updates/

【讨论】:

  • @bernard-darnton GeolocationService 是静态类吗?我必须添加什么作为使用(令人惊讶的是 vs 没有任何建议)
  • 我收到该错误严重性代码描述项目文件行抑制状态错误 CS0016 无法写入输出文件'C:\Users\user\source\repos\BlazorDeviceInterop\Darnton.Blazor.DeviceInterop\Darnton。 Blazor.DeviceInterop.xml' - '找不到路径的一部分'C:\Users\user\source\repos\BlazorDeviceInterop\Darnton.Blazor.DeviceInterop\Darnton.Blazor.DeviceInterop.xml'。 Darnton.Blazor.DeviceInterop C:\Users\Test\BlazorDeviceInterop\Darnton.Blazor.DeviceInterop\CSC 1. 重要的是 C:\Users\user\source\repos\BlazorDeviceInterop\ 不是我的路径,看起来像是你的路径.
  • 另外,我尝试过使用 Nuget,但它不起作用。仍然安装 NuGet 后,我​​没有命名空间
  • 我试过了。它工作正常:)
【解决方案2】:

您可以在使用 JS 互操作时使用 @Bertramp 建议。仅通过 JS 函数对其进行扩展,该函数应为互操作调用返回一个值。这个方法会是这样的:

const getCoords = async () => {
    const pos = await new Promise((resolve, reject) => {
        navigator.geolocation.getCurrentPosition(resolve, reject);
    });
    return [pos.coords.longitude, pos.coords.latitude];       
};

【讨论】:

  • 我认为这是正确的方向,但看起来仍然行不通。 Microsoft.JSInterop.JSException:在“窗口”中找不到“getCoords”。错误:在“窗口”中找不到“getCoords”。我将更改推送到github.com/kkrysztofczyk/GetLocation
【解决方案3】:

您可以使用 JS 互操作从 Blazor 组件调用 JS 函数,然后使用 navigtor.geolocation API。当您调用地理定位 API 时,您的浏览器会自动请求权限

@page "/call-js-example-1"
@inject IJSRuntime JS

    <button @onclick="GetLocation">Get location</button>

@code {

    private async Task<(long,long)> GetLocation()
    {
        ValueTuple<long,long>location = await JS.InvokeAsync<(long longitude, long lattitude)>("getLocation");
        return location;
    }
}

&lt;script&gt;标签中的函数添加到Pages/_Host.cshtml

<script>
  window.getLocation= () => {
    if(navigator.geoLocation) {
      // Do something with the navigator.geolocation.getCurrentPosition function
    }
  };
</script>

【讨论】:

  • 看起来 "new(await JS.InvokeAsync("getLocation")); "需要 c# 9.0。这可能与 C#8.0 有关吗?错误:功能“目标类型对象创建”在 C# 8.0 中不可用。请使用 9.0 或更高版本的语言。
  • 我已经编辑了 C#9.0 之前工作的答案
  • 不幸的是仍然不起作用:(。我收到这样一个错误 Microsoft.JSInterop.JSException:执行 JS 互操作时发生异常:Null 对象无法转换为值类型。有关更多信息,请参阅 InnerException详情。
  • 我把代码放到了 repo github.com/kkrysztofczyk/GetLocation 中。这可能有助于重现问题
【解决方案4】:

最后我将这样的脚本添加到 _Host.cshtml

<script>
    window.getCoords = async () => {            
        const pos = await new Promise((resolve, reject) => {
            navigator.geolocation.getCurrentPosition(resolve, reject);
        });
        document.getElementById("SearchPoint").value = pos.coords.latitude + ', ' + pos.coords.longitude

        if ("createEvent" in document) {
            var evt = document.createEvent("HTMLEvents");
            evt.initEvent("change", false, true);
            document.getElementById("SearchPoint").dispatchEvent(evt);
        }
        else
            document.getElementById("SearchPoint").fireEvent("onchange");

    };
</script>

以及从 blazor 组件调用它的代码:

private void GetLocation()
{
    JS.InvokeAsync<(long longitude, long lattitude)>("getCoords");
}

【讨论】:

    【解决方案5】:

    我花了很长时间才弄明白,但我想分享一个解决方案来帮助其他陷入困境的人。此解决方案适用于 Blazor 服务器应用。

    首先将您的脚本添加到 _Layout.cshtml 文件的正文中。它看起来像这样。

    <body>
    @RenderBody()
    <script>
    window.getCoords = async () => {
        const pos = await new Promise((resolve, reject) => {
            navigator.geolocation.getCurrentPosition(resolve, reject);
        });
        return [pos.coords.longitude, pos.coords.latitude];
    };
    <script>
    </body>
    

    接下来,您需要将 OnAfterRenderAsync 方法添加到您的类中。此方法将调用 _Layout.cshtml 中的 JavaScript 函数

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
      var result = await JS.InvokeAsync<JsonArray>("getCoords");
    }
    

    结果变量现在应该包含经度和纬度。

    请注意,我期望的返回类型是 JsonArray。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-31
      • 1970-01-01
      • 2018-10-17
      • 2018-09-17
      • 1970-01-01
      相关资源
      最近更新 更多