Blazor 谷歌地图在程序化标记点击时刷新
我有一个 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
...事实证明我错过了一些非常简单的事情。 ::sigh::
在我的 OnAfterRenderAsync 函数中:
应该读作:
我在页面刷新时随时运行 LoadMapPins。 ::叹气::
抱歉浪费了时间。不过,我会把这个问题留在这里——也许其他人可以从中得到一些用处。
...and it turns out that I was missing something incredibly simple. ::sigh::
In my OnAfterRenderAsync function:
should read as:
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.