Blazor 服务器 : load js scripts only on certain pages, 并非全部

标签 blazor

建议在 _Host.cshtml 中加载 JS 库,而不是在布局中(也不在不允许的组件中)

但是这样做,怎么可能为一个页面加载一些脚本而为另一个页面加载一些脚本?例如。我只想要在我使用它们的页面中使用 googlemaps 的东西或数据表的东西,而不是全部(浪费空间/内存/加载时间)。

谢谢

最佳答案

正如评论中所讨论的,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 ,因为脚本将异步加载,所以你需要 await在 C# 代码中。
loaded数组是为了避免再次重新加载脚本。任何脚本一旦加载,就会保持加载状态,除非用户刷新页面。所以负载只发生一次。

在需要确保加载库的页面/组件上,我需要注入(inject) 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

关于Blazor 服务器 : load js scripts only on certain pages, 并非全部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58976579/

相关文章:

c# - 如何在单个网站中运行多个 Blazor 应用程序

c# - 如何在 C# 8+ 中从 WebAPI 发送 IAsyncEnumerator 并通过 HttpClient 传输数据?

blazor - 动态呈现 Blazor 组件的推荐方法是什么?

asp.net-core - 如何在asp.net core Blazor中调用js脚本文件

c# - 如何从 Blazor 页面修改布局?

c# - Blazor Framework 如何在属性值更改时收到通知

asp.net-core - blazorstrap InputType.select 未绑定(bind)

c# - Xunit 内存数据库中新的 DBContext 类具有实时数据

blazor - 在 Blazor 中使用组件时从子级到父级进行通信

asp.net-core - C# Blazor : How to use a dynamic @typeparam in Code behind?