Blazor 谷歌地图在程序化标记点击时刷新

发布于 2025-01-15 00:19:53 字数 3312 浏览 4 评论 0原文

我有一个 Blazor 应用程序,我可以在其中在谷歌地图上放置标记。最终用户可以单击标记以使其更新地图下方显示的“选择位置”下拉列表的选定值 - 这非常有效。

如果用户从下拉列表中选择地图位置,我将调用一个函数“clickPin”,该函数以编程方式单击该地图位置的图钉。

问题是,在以编程方式单击标记后,我立即看到标记弹出一瞬间,然后地图刷新。我不确定它是否是像提交按钮一样的下拉菜单(我不认为它是...?)、强制重新加载的脚本或 Google 地图中内置的内容。

我已经在google和stackoverflow上进行了搜索,但我还没有找到甚至提到这个问题的解决方案。

以下是我的代码的重要部分:

首先,处理地图的脚本:

var mapOptions = null;
var map = null;
var infoWindow = null;
var markers = [];

function initialize(coords) {
    mapOptions = {
        center: new google.maps.LatLng(35.68484978380786, -86.60681036623693),
        zoom: 7,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    infoWindow = new google.maps.InfoWindow();
    map = new google.maps.Map(document.getElementById("map"), mapOptions);
}

function addpins(name, lat, lng, desc) {
    var data = { name, lat, lng, desc };
    var myLatLng = new google.maps.LatLng(data.lat, data.lng);
    var marker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        title: data.name
    });
    markers.push(marker);
    (function (marker, data) {
        google.maps.event.addListener(marker, "click", function (e) {
            infoWindow.setContent(data.desc);
            infoWindow.open(map, marker);
        });
    })(marker, data);
    (function bindInfoWindow(marker, map, infoWindow) {
        google.maps.event.addListener(marker, 'click', function () {
            Array.from(document.querySelector("#test").options).forEach(function (option_element) {
                let option_text = option_element.text;

                if (option_text === marker.title) {
                    option_element.selected = true;
                }
            });
        });
    })(marker, map, infoWindow);
}

function clickPin(txt) {
    markers.forEach(function (m) {
        let val = m.title;
        if (txt === val) {
            google.maps.event.trigger(m, 'click');
        }
    });
}

其次,剃刀页面:

@inject IJSRuntime JSRuntime

<div id="map" style="height:400px;width:100%;"></div>
                    
<select id="test" value="@testId" @onchange="@ClickPin">
     @foreach (var inf in Infos)
     {
        <option value="@inf.Name">@inf.Name</option>
     }
</select>

第三,调用“clickPin”:

private int? testId { get; set; }

internal async Task ClickPin(ChangeEventArgs e)
{
    var selVal = e.Value.ToString();
    await JSRuntime.InvokeVoidAsync("clickPin", new string[] { selVal });
}

我希望我错过了一些非常简单的东西。欢迎任何建议。

...事实证明我遗漏了一些非常简单的东西。 ::sigh::

在我的 OnAfterRenderAsync 函数中:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    Infos = await Info.GetAll();
    if (firstRender) { StateHasChanged(); }
    else { await LoadMapPins(); }
}

应该读作:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    Infos = await Info.GetAll();
    if (firstRender) { StateHasChanged(); await LoadMapPins(); }
    //else { await LoadMapPins(); }
}

我在页面刷新时随时运行 LoadMapPins。 ::叹气::

抱歉浪费了时间。不过,我会把这个问题留在这里——也许其他人可以从中得到一些用处。

谢谢, 卡萨克斯

I have a Blazor app in which I place markers on a google map. The end user can click on a marker to have it update the selected value of a "select location" dropdown displayed below the map -- this works perfectly.

If the user selects a map location from the dropdown, I call a function, "clickPin", that programatically clicks the pin for that map location.

The trouble is that immediately after the marker is clicked programatically I see the Marker pop up for a split second, then the map refreshes. I'm not sure if it's the dropdown acting like a submit button (I don't think it is...?), the script forcing a reload, or something built into Google Maps.

I have searched all over google and stackoverflow, and I have not been able to find a solution that even mentions this problem.

Here are the important parts of my code:

First, the scripts to deal with the maps:

var mapOptions = null;
var map = null;
var infoWindow = null;
var markers = [];

function initialize(coords) {
    mapOptions = {
        center: new google.maps.LatLng(35.68484978380786, -86.60681036623693),
        zoom: 7,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    infoWindow = new google.maps.InfoWindow();
    map = new google.maps.Map(document.getElementById("map"), mapOptions);
}

function addpins(name, lat, lng, desc) {
    var data = { name, lat, lng, desc };
    var myLatLng = new google.maps.LatLng(data.lat, data.lng);
    var marker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        title: data.name
    });
    markers.push(marker);
    (function (marker, data) {
        google.maps.event.addListener(marker, "click", function (e) {
            infoWindow.setContent(data.desc);
            infoWindow.open(map, marker);
        });
    })(marker, data);
    (function bindInfoWindow(marker, map, infoWindow) {
        google.maps.event.addListener(marker, 'click', function () {
            Array.from(document.querySelector("#test").options).forEach(function (option_element) {
                let option_text = option_element.text;

                if (option_text === marker.title) {
                    option_element.selected = true;
                }
            });
        });
    })(marker, map, infoWindow);
}

function clickPin(txt) {
    markers.forEach(function (m) {
        let val = m.title;
        if (txt === val) {
            google.maps.event.trigger(m, 'click');
        }
    });
}

Second, The razor page:

@inject IJSRuntime JSRuntime

<div id="map" style="height:400px;width:100%;"></div>
                    
<select id="test" value="@testId" @onchange="@ClickPin">
     @foreach (var inf in Infos)
     {
        <option value="@inf.Name">@inf.Name</option>
     }
</select>

Third, calling "clickPin":

private int? testId { get; set; }

internal async Task ClickPin(ChangeEventArgs e)
{
    var selVal = e.Value.ToString();
    await JSRuntime.InvokeVoidAsync("clickPin", new string[] { selVal });
}

I'm hoping I'm missing something incredibly simple. Any suggestions are welcome.

...and it turns out that I was missing something incredibly simple. ::sigh::

In my OnAfterRenderAsync function:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    Infos = await Info.GetAll();
    if (firstRender) { StateHasChanged(); }
    else { await LoadMapPins(); }
}

should read as:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    Infos = await Info.GetAll();
    if (firstRender) { StateHasChanged(); await LoadMapPins(); }
    //else { await LoadMapPins(); }
}

I was running LoadMapPins anytime the page refreshed. ::sigh::

Sorry for the wasted time. I'll leave the question here, though -- maybe someone else can get some use out of it.

Thanks,
Carthax

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

煮酒 2025-01-22 00:19:53

...事实证明我错过了一些非常简单的事情。 ::sigh::

在我的 OnAfterRenderAsync 函数中:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    Infos = await Info.GetAll();
    if (firstRender) { StateHasChanged(); }
    else { await LoadMapPins(); }
}

应该读作:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    Infos = await Info.GetAll();
    if (firstRender) { StateHasChanged(); await LoadMapPins(); }
    //else { await LoadMapPins(); }
}

我在页面刷新时随时运行 LoadMapPins。 ::叹气::

抱歉浪费了时间。不过,我会把这个问题留在这里——也许其他人可以从中得到一些用处。

...and it turns out that I was missing something incredibly simple. ::sigh::

In my OnAfterRenderAsync function:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    Infos = await Info.GetAll();
    if (firstRender) { StateHasChanged(); }
    else { await LoadMapPins(); }
}

should read as:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    Infos = await Info.GetAll();
    if (firstRender) { StateHasChanged(); await LoadMapPins(); }
    //else { await LoadMapPins(); }
}

I was running LoadMapPins anytime the page refreshed. ::sigh::

Sorry for the wasted time. I'll leave the question here, though -- maybe someone else can get some use out of it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文