建议将JS库加载到_Host.cshtml中,而不要加载到布局中(不允许加载到组件中)
但是这样做,如何为一个页面加载一些脚本,为另一个页面加载一些脚本呢?例如。我只希望在使用Googlemaps或datatable的页面中使用它们,而不是全部(浪费空间/内存/加载时间)。
谢谢
答案 0 :(得分:4)
如评论中所述,Blazor是SPA,因此Blazor页面上可以加载任何加载的脚本,因为它是同一页面。
但是,您没有将它们全部列出在_Host.cshtml
中,实际上您可能只想在需要时才加载特定的脚本(例如,并非所有用户都使用特定的脚本)。需要脚本的页面/组件)。
可以使用JS Interop动态加载脚本。我创建了以下scriptLoader.js
库,并将其包含在_Host.cshtml
中:
// loadScript: returns a promise that completes when the script loads
window.loadScript = function (scriptPath) {
// check list - if already loaded we can ignore
if (loaded[scriptPath]) {
console.log(scriptPath + " already loaded");
// return 'empty' promise
return new this.Promise(function (resolve, reject) {
resolve();
});
}
return new Promise(function (resolve, reject) {
// create JS library script element
var script = document.createElement("script");
script.src = scriptPath;
script.type = "text/javascript";
console.log(scriptPath + " created");
// flag as loading/loaded
loaded[scriptPath] = true;
// if the script returns okay, return resolve
script.onload = function () {
console.log(scriptPath + " loaded ok");
resolve(scriptPath);
};
// if it fails, return reject
script.onerror = function () {
console.log(scriptPath + " load failed");
reject(scriptPath);
}
// scripts will load at end of body
document["body"].appendChild(script);
});
}
// store list of what scripts we've loaded
loaded = [];
这将创建一个script
元素,并将其追加到文档的body
元素中。由于脚本将异步加载,因此它返回一个Promise,因此您需要在C#代码中使用await
。
这里有loaded
数组,以避免再次重新加载脚本。除非用户刷新页面,否则任何脚本一旦加载就保持加载状态。因此,负载仅发生一次。
在需要确保已加载库的页面/组件上,我需要注入IJSruntime
...
@inject IJSRuntime jsRuntime
然后调用它。.
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// invoke script loader
Console.WriteLine("Loading jQuery");
await jsRuntime.InvokeVoidAsync("loadScript", "https://code.jquery.com/jquery-3.4.1.js");
await jsRuntime.InvokeVoidAsync("loadScript", "myJQueryTest.js");
Console.WriteLine("Invoking jQuery");
await jsRuntime.InvokeVoidAsync("setH1", "Hello world!");
Console.WriteLine("Invoked JQuery");
await base.OnAfterRenderAsync(firstRender);
}
myJQueryTest.js
很简单:
window.setH1 = function (message) {
$('h1').text(message);
}
已创建演示回购:https://github.com/conficient/BlazorDynamicScriptLoad