Blazor Server项目中如何在Razor页面HTML部分调用JS操作Canvas
解决Blazor Server中循环调用JS绘制Canvas的问题
1. 确保JavaScript文件已正确引用
在Blazor Server的_Host.cshtml文件中,把MyJavaScript.js的引用放在</body>标签前,确保JS文件能被正确加载:
<script src="~/js/MyJavaScript.js"></script>
2. 在组件生命周期中调用JS函数
Blazor不允许直接在HTML模板里调用JS函数,必须通过IJSRuntime在组件渲染完成后执行(此时Canvas元素已经挂载到DOM中)。推荐使用OnAfterRenderAsync生命周期方法来实现:
修改MyPage.razor的完整代码如下:
@page "/mypage" @inject IJSRuntime JSRuntime <div> @foreach(MyData anData in ListOfMyData){ <div> <canvas id="@anData.id" class="myDataImage"></canvas> </div> } </div> @code { private List<MyData> ListOfMyData { get; set; } = new(); // 模拟数据加载逻辑,实际可替换为API请求等 protected override async Task OnInitializedAsync() { ListOfMyData = await LoadMyDataAsync(); } // 组件渲染完成后调用JS绘制Canvas protected override async Task OnAfterRenderAsync(bool firstRender) { // 首次渲染或数据更新时执行绘制 if (firstRender || ListOfMyData.Any()) { foreach (var anData in ListOfMyData) { // 调用JS函数,传入Canvas ID和对应数据 await JSRuntime.InvokeVoidAsync("drawImage", anData.id, anData); } } } // 模拟数据加载方法 private Task<List<MyData>> LoadMyDataAsync() { return Task.FromResult(new List<MyData> { new MyData { id = "canvas_01", /* 其他自定义数据字段 */ }, new MyData { id = "canvas_02", /* 其他自定义数据字段 */ } }); } }
3. 调整JS函数适配Blazor传递的数据
Blazor会自动将C#的MyData对象序列化为JSON,JS函数中可以直接使用传入的data对象:
function drawImage(canvasID, data){ let thisCanvas = document.getElementById(canvasID); if (!thisCanvas) return; // 兼容DOM未加载完成的情况 thisCanvas.width = 200; // 设置实际画布宽度 thisCanvas.height = 150; // 设置实际画布高度 let ctx = thisCanvas.getContext('2d'); ctx.beginPath(); // 根据data中的数据绘制图形,示例: // ctx.arc(data.centerX, data.centerY, data.radius, 0, Math.PI * 2); // ctx.fillStyle = data.fillColor; // ctx.fill(); }
关键注意事项
- 确保
MyData类的属性是公共访问修饰符,否则Blazor无法将其正确序列化为JS可识别的对象。 - 如果
ListOfMyData是动态更新的,在数据更新后需要调用StateHasChanged()触发组件重新渲染,OnAfterRenderAsync会自动重新执行绘制逻辑。 - 不要在
OnInitializedAsync中直接调用JS,此时DOM尚未渲染完成,无法找到对应的Canvas元素。
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

