簡體   English   中英

如何從 Blazor 組件使用 jQuery UI

[英]How to use jQuery UI from Blazor component

我正在研究一些 Blazor 示例,在嘗試使用一些 JSInterop 解決方案時,我遇到了 jQuery UI 元素的問題。 我不是一個精通 Javascript 的程序員,但我對 .NET 足夠精通,所以我可能會遺漏一些簡單的東西。 我嘗試使用的第一個 jQuery UI 組件是“可調整大小”組件,可在此處找到: https : //jqueryui.com/resizable/

這是我當前的代碼的樣子:

索引.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
    <app>Loading...</app>

    <script src="_framework/blazor.server.js"></script>
    <script>
        $( function() {
            $( "#resizable" ).resizable();
        });
    </script>
</body>
</html>

我確定問題不在於加載庫,並且我在加載blazor.server.js后放置了腳本。

現在,我的Index.cshtml在 html 部分有以下內容:

<body>
    <div class="container-fluid">
        <div id="resizable" class="ui-widget-content">
            <div class="row row-no-gutters" style="width: 100%; height: 50%">
                <h3 class="ui-widget-header">Resizable</h3>
            </div>
        </div>
    </div>
</body>

理想情況下,這將產生一個可調整大小的 div,但生成的 html 元素不可調整大小。 據我了解,Blazor JSInterop 不再需要注冊 JS 函數。 我究竟做錯了什么?

問題在於時間:您的 jQuery 函數在您的 Blazor 應用程序呈現之前執行。

我解決這個問題的方法是用一個命名函數(例如onBlazorReady )替換“onready”( $(...) )函數,然后我在正確的時間從我的 Blazor 的MainLayout組件調用。

正確的時間是OnAfterRender

例如:

MainLayout.razor:

@code {
   [Inject]
   protected IJSRuntime JsRuntime { get; set; }

   protected override void OnAfterRender(bool firstRender)
   {
       if (firstRender)
           JsRuntime.InvokeVoidAsync("onBlazorReady");
   }
}

索引.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
    <app>Loading...</app>

    <script src="_framework/blazor.server.js"></script>
    <script>
        onBlazorReady() {
            $("#resizable").resizable();
        });
    </script>
</body>
</html>

如您所見,我正在注入IJSInterop以便在 LayoutComponent 呈現后調用我的onBlazorReady JS 函數。

像這樣對我來說很好用,從 jquery ui 添加日期選擇器:

Razor 組件文件。

@code {
    protected override async void OnAfterRender(bool firstRender)
    {
        await jsRuntime.InvokeVoidAsync("addDatePicker");
        base.OnAfterRender(firstRender);
    }
}

全局剃刀文件:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Magiro.Blazor</title>
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
    <app>
        @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
    </app>

    <script src="_framework/blazor.server.js"></script>
    <script>
        window.addDatePicker = () => {
            $(".datepicker").datepicker();
        }
    </script>
</body>
</html>

最可能的原因是時機。 jQuery 函數在 DOM 元素存在之前執行。

您應該將 JS 代碼注冊為互操作函數,然后在OnAfterRender事件中調用它。

不再需要在全局索引頁面(ASP.NET Core 5.0 中的_Hosts.cshtml中添加方法,這將使用特定於視圖的邏輯和依賴項填充這些文件。 至少在 v5 中,我們有IJSObjectReference允許我們直接從我們的.razor文件中調用$('table').DataTable() ,如下所示:

<table>
    <thead>
        <tr>
            <td>Id</td>
            <td>Name</td>
        </tr>
    </thead>
    <tbody>
            <!-- your data -->
    </tbody>
</table>

@code {
    [Inject]
    protected IJSRuntime JSRuntime { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender) {
        if (firstRender) {
            var jQuery = await JSRuntime.InvokeAsync<IJSObjectReference>("$", "table");
            await jQuery.InvokeVoidAsync("DataTable");
        }
    }
}

也可以使用匿名類型將選項傳遞給插件。 例如,要禁用搜索,我們會在 JS 中調用

$('#example').dataTable({
  "searching": false
});

在 Blazor 中,我們創建了一個具有相同結構的匿名類型,並將其作為參數傳遞給DataTable調用:

var options = new {
    searching = false
};
await jQuery.InvokeVoidAsync("DataTable", options);

是的,“ Blazor JSInterop不再需要注冊JS函數”。 但據我所知,您沒有使用JSInterop。 我認為您根本不應該使用Jquery。 最重要的是,您應該創建組件來產生這種功能。 JSInterop僅應在不可能的情況下使用。 JSInterop是一個臨時解決方案,用於在Blazor應用程序和DOM之間提供通信,直到Web Assembly變得足夠成熟以可以直接訪問DOM為止,而無需JavaScript的中介。 再一次,Blazor模式,實際上是Razor組件,希望您創建組件,而不使用舊的jQuery庫。

有關創建樹視圖的問題堆棧溢出。 它完全是用JavaScript創建的。 我對開發人員的回答與我給您的相同。 實際上,他完全在Blazor中創建了一個樹視圖組件。

通常你不需要像ready任何 JQuery 函數,你可以簡單地將所有需要的代碼放入你的自定義 js 函數中,這些函數應該在你的組件的 ON_LOAD 上運行,正如@Sipke Schoorstra 在上面的回答中所說的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM