在组件中导入 javascript 文件并在多个页面上使用时出现 Blazor JSRuntime 问题

Posted

技术标签:

【中文标题】在组件中导入 javascript 文件并在多个页面上使用时出现 Blazor JSRuntime 问题【英文标题】:Blazor JSRuntime problem when importing javascript file in component and using on multiple pages 【发布时间】:2021-08-13 12:24:14 【问题描述】:

我有一个使用 .js 文件运行的模态组件。为了附加 javascript,我在 OnAfterRenderAsync 函数中进行了调用。

protected override async Task OnAfterRenderAsync(bool firstRender)
    
        if (firstRender)
        
            var libraryName = GetType().Assembly.GetName().Name;
            await JSRuntime.InvokeAsync<IJSObjectReference>("import", $"./_content/libraryName/scripts/aria.modal.min.js");
        
    

当我将此组件放置在特定页面上时,这可以正常工作。 但是,当我在不同的页面上调用相同的组件并从一个页面导航到另一个页面时,脚本无法加载且没有任何错误,并且除非我重新加载页面,否则模式将无法打开。

我尝试调用只有一行代码alert("bla"); 的简单.js 文件,同样的事情发生了。它在我第一次导航到该页面时起作用,然后当我导航到具有相同组件的另一个页面时,脚本失败而没有任何错误。

@inject IJSRuntime JSRuntime

<div id="@Id" data-modal data-modal-manual-close hidden class="c-modal @Id-modal" role="dialog" tabindex="-1">
    <div data-modal-document role="document">

        @if (!hasBody)
        
            <h2 class="c-modal__title @Id-modal__head" id="tableLabel">
                @HeaderContent
            </h2>
            <div class="c-modal__body @Id-modal__body">
                @BodyContent
            </div>

            <footer class="c-modal__footer @Id-modal__footer">
                <button class="btn btn--primary">Select</button>
                <button data-modal-close-btn class="btn btn--outline">Cancel</button>
            </footer>

            <button data-modal-close-btn aria-labelledby="close-button-label" class="btn c-modal__close-btn">
                <span id="close-button-label" hidden>Close</span>
                <svg   viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">
                    <path d="M18.4652 8.15127L13.6165 13L18.4652 17.8487L16.849 19.465L12.0002 14.6162L7.1515 19.465L5.53526 17.8487L10.384 13L5.53526 8.15127L7.1515 6.53502L12.0002 11.3838L16.849 6.53502L18.4652 8.15127Z" fill="currentColor" />
                </svg>
            </button>
        
        else
        
            @BodyContent
        
    </div>
</div>

@code 
    [Parameter]
    public bool hasBody  get; set; 
    [Parameter]
    public RenderFragment BodyContent  get; set; 
    [Parameter]
    public RenderFragment HeaderContent  get; set; 
    [Parameter] public string Id  get; set; 

    protected override async Task OnAfterRenderAsync(bool firstRender)
    
        if (firstRender)
        
            var libraryName = GetType().Assembly.GetName().Name;
            await JSRuntime.InvokeAsync<IJSObjectReference>("import", $"./_content/libraryName/scripts/aria.modal.min.js");
        
    

【问题讨论】:

【参考方案1】:

我认为您需要在您的 razor 页面中实现 Dispose。 喜欢:

...
@implements IAsyncDisposable
...
@code 
    private IJSObjectReference module;
...
            module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", $"./_content/libraryName/scripts/aria.modal.min.js");
...
async ValueTask IAsyncDisposable.DisposeAsync()
    
        if (module is not null)
        
            await module.DisposeAsync();
        
    

【讨论】:

我已经试过了。它不能解决问题。

以上是关于在组件中导入 javascript 文件并在多个页面上使用时出现 Blazor JSRuntime 问题的主要内容,如果未能解决你的问题,请参考以下文章

什么是从同一个文件中导入多个组件的正确方法,而不是导入每个组件

如何在 Typescript 文件中导入 Svelte 组件?

如何在 Vue 组件中导入外部函数?

在反应中导入多个文件

在 React TypeScript 组件中导入 Javascript

如何避免在每个测试文件中导入组件所需的所有内容?