Blazor组件自做六 : 使用JS隔离封装Baidu地图
1. 运行截图
演示地址
2. 在文件夹wwwroot/lib,添加baidu子文件夹,添加baidumap.js文件
2.1 跟上一篇类似,用代码方式异步加载API,脚本生成新的 body > script 元素添加到页面文档,使用异步加载回调 initMapsG 方法初始化地图.
var map = null;
var containerid = null;
export function addScript(key, elementId, dotnetRef, backgroundColor, controlSize) {
if (!key || !elementId) {
return;
}
containerid = elementId;
let url = "https://api.map.baidu.com/api?v=3.0&ak=";
let scriptsIncluded = false;
let scriptTags = document.querySelectorAll('body > script');
scriptTags.forEach(scriptTag => {
if (scriptTag) {
let srcAttribute = scriptTag.getAttribute('src');
if (srcAttribute && srcAttribute.startsWith(url)) {
scriptsIncluded = true;
return true;
}
}
});
if (scriptsIncluded) {
initMapsG();
return true;
}
url = url + key + "&callback=initMapsG";
let script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
return false;
}
2.2 初始化地图方法.
export function resetMaps(elementId) {
initMaps(elementId);
}
function initMapsG() {
initMaps(containerid);
}
function initMaps(elementId) {
// 创建地图实例
map = new BMap.Map(elementId, {
coordsType: 5 // coordsType指定输入输出的坐标类型,3为gcj02坐标,5为bd0ll坐标,默认为5。指定完成后API将以指定的坐标类型处理您传入的坐标
});
// 创建点坐标
var point = new BMap.Point(116.47496, 39.77856);
// 初始化地图,设置中心点坐标和地图级别
map.centerAndZoom(point, 15);
//开启鼠标滚轮缩放
map.enableScrollWheelZoom(true);
map.addControl(new BMap.NavigationControl());
map.addControl(new BMap.ScaleControl());
map.addControl(new BMap.OverviewMapControl());
map.addControl(new BMap.MapTypeControl());
// 仅当设置城市信息时,MapTypeControl的切换功能才能可用
map.setCurrentCity("北京");
}
2.3 百度地定位图API,并开启SDK辅助定位.
export function geolocation(wrapper) {
var geolocation = new BMap.Geolocation();
// 开启SDK辅助定位
geolocation.enableSDKLocation();
geolocation.getCurrentPosition(function (r) {
let geolocationitem;
if (this.getStatus() == BMAP_STATUS_SUCCESS) {
var mk = new BMap.Marker(r.point);
map.addOverlay(mk);
map.panTo(r.point);
console.log('您的位置:' + r.point.lng + ',' + r.point.lat);
let lng = r.point.lng;
let lat = r.point.lat;
geolocationitem= {
"Longitude":lng,
"Latitude" : lat,
"Status": '您的位置:' + r.point.lng + ',' + r.point.lat
};
}
else {
geolocationitem= {
"Longitude": 0,
"Latitude": 0,
"Status": 'failed' + this.getStatus()
};
}
wrapper.invokeMethodAsync('GetResult', geolocationitem);
return geolocationitem;
});
}
3. 打开Components文件夹 , 新建baidu文件夹, 新建BaiduMap.razor文件
razor代码
@implements IAsyncDisposable
@inject IJSRuntime JS
@namespace Blazor100.Components
@inject IConfiguration config
@code{
///
/// 获得/设置 错误回调方法
///
[Parameter]
public Func? OnError { get; set; }
///
/// 获得/设置 BaiduKey
/// 为空则在 IConfiguration 服务获取 "BaiduKey" , 默认在 appsettings.json 文件配置
///
[Parameter]
public string? Key { get; set; }
///
/// 获得/设置 style
///
[Parameter]
public string Style { get; set; } = "height:700px;width:100%;";
///
/// 获得/设置 ID
///
[Parameter]
public string ID { get; set; } = "container";
///
/// 获得/设置 定位结果回调方法
///
[Parameter]
public Func? OnResult { get; set; }
private IJSObjectReference? module;
private DotNetObjectReference? InstanceGeo { get; set; }
private string key = String.Empty;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
key = Key ?? config["BaiduKey"];
module = await JS.InvokeAsync("import", "./lib/baidu/baidumap.js");
InstanceGeo = DotNetObjectReference.Create(this);
while (!(await Init()))
{
await Task.Delay(500);
}
//await module!.InvokeVoidAsync("initMaps");
}
}
public async Task Init() => await module!.InvokeAsync("addScript", new object?[] { key, ID, null, null, null });
public async Task OnOptionsChanged(ViewerOptions options) => await module!.InvokeVoidAsync("init", options);
public async Task ResetMaps() => await module!.InvokeVoidAsync("resetMaps", ID);
public async Task OnBtnClick(string btn) => await module!.InvokeVoidAsync(btn);
///
/// 获取定位
///
public virtual async Task GetLocation()
{
try
{
await module!.InvokeVoidAsync("geolocation", InstanceGeo);
}
catch (Exception e)
{
if (OnError != null) await OnError.Invoke(e.Message);
}
}
///
/// 定位完成回调方法
///
///
///
[JSInvokable]
public async Task GetResult(BaiduItem geolocations)
{
try
{
if (OnResult != null) await OnResult.Invoke(geolocations);
}
catch (Exception e)
{
if (OnError != null) await OnError.Invoke(e.Message);
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
//await module.InvokeVoidAsync("destroy", Options);
await module.DisposeAsync();
}
}
}
4. Components/baidu文件夹 , 新建文件夹, 新建BaiduItem.cs文件
Baidu定位数据类
using System;
using System.ComponentModel;
namespace Blazor100.Components
{
///
/// Baidu定位数据类
///
public class BaiduItem
{
///
/// 状态
///
///
[DisplayName("状态")]
public string? Status { get; set; }
///
/// 纬度
///
///
[DisplayName("纬度")]
public decimal Latitude { get; set; }
///
/// 经度
///
///
[DisplayName("经度")]
public decimal Longitude { get; set; }
}
}
5. Pages文件夹添加BaiduMapPage.razor文件,用于演示组件调用.
BaiduMapPage.razor
@page "/baidumap"
百度地图 Baidu Map
@message
BaiduMapPage.razor.cs
using Blazor100.Components;
namespace Blazor100.Pages;
///
/// 百度地图 BaiduMap
///
public sealed partial class BaiduMapPage
{
private string message;
private BaiduItem baiduItem;
private Task OnResult(BaiduItem geolocations)
{
baiduItem = geolocations;
this.message = baiduItem.Status;
StateHasChanged();
return Task.CompletedTask;
}
private Task OnError(string message)
{
this.message = message;
StateHasChanged();
return Task.CompletedTask;
}
}
6. _Imports.razor加入一行引用组件的命名空间.
@using Blazor100.Components
7. 首页引用组件演示页
或者 Shared/NavMenu.razor
添加导航
8. F5运行程序
至此,使用JS隔离封装Baidu地图大功告成! Happy coding!
Blazor组件自做系列